blob: c014ae4c5a291c0f4131bb229a929ba8873d2b6e [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"
Himani Chawlac07fda02020-12-09 16:21:21 +053035 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000036 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
37 "github.com/opencord/voltha-lib-go/v4/pkg/log"
38 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050039 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000040 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
41 "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 oop "github.com/opencord/voltha-protos/v4/go/openolt"
45 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000046)
47
48/*
49// Constants for number of retries and for timeout
50const (
51 MaxRetry = 10
52 MaxTimeOutInMs = 500
53)
54*/
55
mpagenko1cc3cb42020-07-27 15:24:38 +000056const (
57 // events of Device FSM
58 devEvDeviceInit = "devEvDeviceInit"
59 devEvGrpcConnected = "devEvGrpcConnected"
60 devEvGrpcDisconnected = "devEvGrpcDisconnected"
61 devEvDeviceUpInd = "devEvDeviceUpInd"
62 devEvDeviceDownInd = "devEvDeviceDownInd"
63)
64const (
65 // states of Device FSM
66 devStNull = "devStNull"
67 devStDown = "devStDown"
68 devStInit = "devStInit"
69 devStConnected = "devStConnected"
70 devStUp = "devStUp"
71)
72
Holger Hildebrandt24d51952020-05-04 14:03:42 +000073//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
74const (
Himani Chawla4d908332020-08-31 12:30:20 +053075 pon = voltha.EventSubCategory_PON
76 //olt = voltha.EventSubCategory_OLT
77 //ont = voltha.EventSubCategory_ONT
78 //onu = voltha.EventSubCategory_ONU
79 //nni = voltha.EventSubCategory_NNI
80 //service = voltha.EventCategory_SERVICE
81 //security = voltha.EventCategory_SECURITY
82 equipment = voltha.EventCategory_EQUIPMENT
83 //processing = voltha.EventCategory_PROCESSING
84 //environment = voltha.EventCategory_ENVIRONMENT
85 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000086)
87
88const (
89 cEventObjectType = "ONU"
90)
91const (
92 cOnuActivatedEvent = "ONU_ACTIVATED"
93)
94
Holger Hildebrandt10d98192021-01-27 15:29:31 +000095type usedOmciConfigFsms int
96
97const (
98 cUploadFsm usedOmciConfigFsms = iota
99 cDownloadFsm
100 cUniLockFsm
101 cUniUnLockFsm
102 cAniConfigFsm
103 cUniVlanConfigFsm
104)
105
106type idleCheckStruct struct {
107 idleCheckFunc func(*deviceHandler, context.Context, string) bool
108 idleState string
109}
110
111var fsmIdleStateFuncMap = map[usedOmciConfigFsms]idleCheckStruct{
112 cUploadFsm: {(*deviceHandler).mibUploadFsmInIdleState, cMibUlFsmIdleState},
113 cDownloadFsm: {(*deviceHandler).mibDownloadFsmInIdleState, cMibDlFsmIdleState},
114 cUniLockFsm: {(*deviceHandler).devUniLockFsmInIdleState, cUniFsmIdleState},
115 cUniUnLockFsm: {(*deviceHandler).devUniUnlockFsmInIdleState, cUniFsmIdleState},
116 cAniConfigFsm: {(*deviceHandler).devAniConfigFsmInIdleState, cAniFsmIdleState},
117 cUniVlanConfigFsm: {(*deviceHandler).devUniVlanConfigFsmInIdleState, cVlanFsmIdleState},
118}
119
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000120const (
121 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000122 drUnset = 0
123 drActivatingOnu = 1
124 drStartingOpenomci = 2
125 drDiscoveryMibsyncComplete = 3
126 drInitialMibDownloaded = 4
127 drTechProfileConfigDownloadSuccess = 5
128 drOmciFlowsPushed = 6
129 drOmciAdminLock = 7
130 drOnuReenabled = 8
131 drStoppingOpenomci = 9
132 drRebooting = 10
133 drOmciFlowsDeleted = 11
134 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000135)
136
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000137var deviceReasonMap = map[uint8]string{
138 drUnset: "unset",
139 drActivatingOnu: "activating-onu",
140 drStartingOpenomci: "starting-openomci",
141 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
142 drInitialMibDownloaded: "initial-mib-downloaded",
143 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
144 drOmciFlowsPushed: "omci-flows-pushed",
145 drOmciAdminLock: "omci-admin-lock",
146 drOnuReenabled: "onu-reenabled",
147 drStoppingOpenomci: "stopping-openomci",
148 drRebooting: "rebooting",
149 drOmciFlowsDeleted: "omci-flows-deleted",
150 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
151}
152
Himani Chawla6d2ae152020-09-02 13:11:20 +0530153//deviceHandler will interact with the ONU ? device.
154type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155 deviceID string
156 DeviceType string
157 adminState string
158 device *voltha.Device
159 logicalDeviceID string
160 ProxyAddressID string
161 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530162 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000163 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000164
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000165 coreProxy adapterif.CoreProxy
166 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530167 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000168
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800169 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800170
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171 pOpenOnuAc *OpenONUAC
172 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530173 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000174 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000175 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530176 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800177 pOnuMetricsMgr *onuMetricsManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000178 exitChannel chan int
179 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000180 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000181 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530182 pLockStateFsm *lockStateFsm
183 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000185 //flowMgr *OpenOltFlowMgr
186 //eventMgr *OpenOltEventMgr
187 //resourceMgr *rsrcMgr.OpenOltResourceMgr
188
189 //discOnus sync.Map
190 //onus sync.Map
191 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000192 collectorIsRunning bool
193 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000194 stopCollector chan bool
195 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000196 uniEntityMap map[uint32]*onuUniPort
mpagenko9a304ea2020-12-16 15:54:01 +0000197 lockVlanConfig sync.Mutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000198 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
199 reconciling bool
200 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000201}
202
Himani Chawla6d2ae152020-09-02 13:11:20 +0530203//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530204func newDeviceHandler(ctx context.Context, cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530205 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206 dh.coreProxy = cp
207 dh.AdapterProxy = ap
208 dh.EventProxy = ep
209 cloned := (proto.Clone(device)).(*voltha.Device)
210 dh.deviceID = cloned.Id
211 dh.DeviceType = cloned.Type
212 dh.adminState = "up"
213 dh.device = cloned
214 dh.pOpenOnuAc = adapter
215 dh.exitChannel = make(chan int, 1)
216 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000217 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000218 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219 dh.stopCollector = make(chan bool, 2)
220 dh.stopHeartbeatCheck = make(chan bool, 2)
221 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530223 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenko9a304ea2020-12-16 15:54:01 +0000224 dh.lockVlanConfig = sync.Mutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000225 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000226 dh.reconciling = false
mpagenkofc4f56e2020-11-04 17:17:49 +0000227 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800229 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
230 dh.pmConfigs = cloned.PmConfigs
231 } /* else {
232 // will be populated when onu_metrics_mananger is initialized.
233 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800234
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235 // Device related state machine
236 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000237 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000239 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
240 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
241 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
242 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
243 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 },
245 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000246 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
247 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
248 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
249 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
250 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
251 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
252 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
253 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254 },
255 )
mpagenkoaf801632020-07-03 10:00:42 +0000256
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 return &dh
258}
259
Himani Chawla6d2ae152020-09-02 13:11:20 +0530260// start save the device to the data model
261func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000262 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000263 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000264 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000265}
266
Himani Chawla4d908332020-08-31 12:30:20 +0530267/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530269func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 logger.Debug("stopping-device-handler")
271 dh.exitChannel <- 1
272}
Himani Chawla4d908332020-08-31 12:30:20 +0530273*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000274
275// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530276// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277
Himani Chawla6d2ae152020-09-02 13:11:20 +0530278//adoptOrReconcileDevice adopts the OLT device
279func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281
dbainbri4d3a0dc2020-12-02 00:33:42 +0000282 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000283 if dh.pDeviceStateFsm.Is(devStNull) {
284 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800288 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
289 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800290 // Now, set the initial PM configuration for that device
291 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
292 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
293 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800294 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 }
298
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299}
300
mpagenko057889c2021-01-21 16:51:58 +0000301func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530302 msgBody := msg.GetBody()
303 omciMsg := &ic.InterAdapterOmciMessage{}
304 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000305 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530306 "device-id": dh.deviceID, "error": err})
307 return err
308 }
309
310 //assuming omci message content is hex coded!
311 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530313 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
314 //receive_message(omci_msg.message)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000315 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530316 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000317 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000318 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000319 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 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 +0530321 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000322 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000323 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530324}
325
Himani Chawla6d2ae152020-09-02 13:11:20 +0530326func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530328 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000329
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000331
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000333 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000334 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000335 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
336 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530337 if dh.pOnuTP == nil {
338 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000341 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530342 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000343 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000345 "device-state": deviceReasonMap[dh.deviceReason]})
346 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000348 //previous state test here was just this one, now extended for more states to reject the SetRequest:
349 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
350 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530351
352 msgBody := msg.GetBody()
353 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
354 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530356 "device-id": dh.deviceID, "error": err})
357 return err
358 }
359
360 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000361 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
362 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000364 defer dh.pOnuTP.unlockTpProcMutex()
365 pDevEntry.lockOnuKVStoreMutex()
366 defer pDevEntry.unlockOnuKVStoreMutex()
367
368 if techProfMsg.UniId > 255 {
369 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
370 techProfMsg.UniId, dh.deviceID))
371 }
372 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800373 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
374 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000375 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800376 return err
377 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 // if there has been some change for some uni TechProfilePath
381 //in order to allow concurrent calls to other dh instances we do not wait for execution here
382 //but doing so we can not indicate problems to the caller (who does what with that then?)
383 //by now we just assume straightforward successful execution
384 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
385 // possible problems to the caller later autonomously
386
387 // deadline context to ensure completion of background routines waited for
388 //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 +0530389 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 dctx, cancel := context.WithDeadline(context.Background(), deadline)
391
Girish Gowdra041dcb32020-11-16 16:54:30 -0800392 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 pDevEntry.resetKvProcessingErrorIndication()
394
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 var wg sync.WaitGroup
396 wg.Add(2) // for the 2 go routines to finish
397 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000398 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
399 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
400 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
Girish Gowdra041dcb32020-11-16 16:54:30 -0800402 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530403 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000404 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 return nil
406}
407
Himani Chawla6d2ae152020-09-02 13:11:20 +0530408func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000409 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 msg *ic.InterAdapterMessage) error {
411
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000413
dbainbri4d3a0dc2020-12-02 00:33:42 +0000414 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000416 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
418 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530419 if dh.pOnuTP == nil {
420 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000421 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530424 }
425
426 msgBody := msg.GetBody()
427 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
428 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530430 "device-id": dh.deviceID, "error": err})
431 return err
432 }
433
434 //compare TECH_PROFILE_DOWNLOAD_REQUEST
435 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436 defer dh.pOnuTP.unlockTpProcMutex()
437 pDevEntry.lockOnuKVStoreMutex()
438 defer pDevEntry.unlockOnuKVStoreMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530439
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440 if delGemPortMsg.UniId > 255 {
441 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
442 delGemPortMsg.UniId, dh.deviceID))
443 }
444 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800445 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
446 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000447 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 -0800448 return err
449 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530450
mpagenkofc4f56e2020-11-04 17:17:49 +0000451 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452
mpagenkofc4f56e2020-11-04 17:17:49 +0000453 // deadline context to ensure completion of background routines waited for
454 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
455 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456
Girish Gowdra041dcb32020-11-16 16:54:30 -0800457 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000458
mpagenkofc4f56e2020-11-04 17:17:49 +0000459 var wg sync.WaitGroup
460 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000462 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000464
Girish Gowdra041dcb32020-11-16 16:54:30 -0800465 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530466}
467
Himani Chawla6d2ae152020-09-02 13:11:20 +0530468func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000469 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530470 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000471
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000473
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000475 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000477 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
478 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530479 if dh.pOnuTP == nil {
480 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 }
485
486 msgBody := msg.GetBody()
487 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
488 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 "device-id": dh.deviceID, "error": err})
491 return err
492 }
493
494 //compare TECH_PROFILE_DOWNLOAD_REQUEST
495 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000496 defer dh.pOnuTP.unlockTpProcMutex()
497 pDevEntry.lockOnuKVStoreMutex()
498 defer pDevEntry.unlockOnuKVStoreMutex()
499
500 if delTcontMsg.UniId > 255 {
501 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
502 delTcontMsg.UniId, dh.deviceID))
503 }
504 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 tpPath := delTcontMsg.TpPath
506 tpID, err := GetTpIDFromTpPath(tpPath)
507 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800509 return err
510 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530514 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 dctx, cancel := context.WithDeadline(context.Background(), deadline)
516
Girish Gowdra041dcb32020-11-16 16:54:30 -0800517 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518 pDevEntry.resetKvProcessingErrorIndication()
519
Himani Chawla26e555c2020-08-31 12:30:20 +0530520 var wg sync.WaitGroup
521 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000522 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530523 cResourceTcont, delTcontMsg.AllocId, &wg)
524 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000525 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
526 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527
Girish Gowdra041dcb32020-11-16 16:54:30 -0800528 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530530 return nil
531}
532
Himani Chawla6d2ae152020-09-02 13:11:20 +0530533//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000534// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
535// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000537 msgID := msg.Header.Id
538 msgType := msg.Header.Type
539 fromTopic := msg.Header.FromTopic
540 toTopic := msg.Header.ToTopic
541 toDeviceID := msg.Header.ToDeviceId
542 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000543 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000544 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
545
546 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000547 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000548 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
549 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000550 {
mpagenko057889c2021-01-21 16:51:58 +0000551 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000552 }
mpagenkoaf801632020-07-03 10:00:42 +0000553 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
554 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000556 }
557 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
558 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000559 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000560
mpagenkoaf801632020-07-03 10:00:42 +0000561 }
562 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
563 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000565 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000566 default:
567 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000568 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000569 "msgType": msg.Header.Type, "device-id": dh.deviceID})
570 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000571 }
572 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000573}
574
mpagenkodff5dda2020-08-28 11:52:01 +0000575//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000576func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
577 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000578 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000579 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000580
mpagenko01e726e2020-10-23 09:45:29 +0000581 var retError error = nil
582 //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 +0000583 if apOfFlowChanges.ToRemove != nil {
584 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000585 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000587 "device-id": dh.deviceID})
588 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000589 continue
590 }
591 flowInPort := flow.GetInPort(flowItem)
592 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000593 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 +0000594 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
595 continue
596 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000597 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000598 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000600 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000601 continue
602 } else {
603 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530604 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000605 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
606 loUniPort = uniPort
607 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000609 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
610 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
611 flowInPort, dh.deviceID)
612 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000613 }
614 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000616 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000617 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000619 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000620 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000622 log.Fields{"device-id": dh.deviceID, "error": err})
623 retError = err
624 continue
625 //return err
626 } else { // if last setting succeeds, overwrite possibly previously set error
627 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000628 }
629 }
630 }
631 }
mpagenko01e726e2020-10-23 09:45:29 +0000632 if apOfFlowChanges.ToAdd != nil {
633 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
634 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000635 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000636 "device-id": dh.deviceID})
637 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
638 continue
639 }
640 flowInPort := flow.GetInPort(flowItem)
641 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 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 +0000643 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
644 continue
645 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
646 } else if flowInPort == dh.ponPortNumber {
647 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000649 "device-id": dh.deviceID, "inPort": flowInPort})
650 continue
651 } else {
652 // this is the relevant upstream flow
653 var loUniPort *onuUniPort
654 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
655 loUniPort = uniPort
656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000658 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
659 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
660 flowInPort, dh.deviceID)
661 continue
662 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
663 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000664 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
665 // if not, we just throw some error here to have an indication about that, if we really need to support that
666 // then we would need to create some means to activate the internal stored flows
667 // after the device gets active automatically (and still with its dependency to the TechProfile)
668 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
669 // also abort for the other still possible flows here
670 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000672 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000673 return fmt.Errorf("improper device state on device %s", dh.deviceID)
674 }
675
mpagenko01e726e2020-10-23 09:45:29 +0000676 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000678 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
679 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000681 //try next flow after processing error
682 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000684 log.Fields{"device-id": dh.deviceID, "error": err})
685 retError = err
686 continue
687 //return err
688 } else { // if last setting succeeds, overwrite possibly previously set error
689 retError = nil
690 }
691 }
692 }
693 }
694 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000695}
696
Himani Chawla6d2ae152020-09-02 13:11:20 +0530697//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000698//following are the expected device states after this activity:
699//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
700// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
702 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000703
mpagenko900ee4b2020-10-12 11:56:34 +0000704 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000705 //note that disableDevice sequences in some 'ONU active' state may yield also
706 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000707 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000708 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000709 //disable-device shall be just a UNi/ONU-G related admin state setting
710 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000711
mpagenkofc4f56e2020-11-04 17:17:49 +0000712 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000713 // disable UNI ports/ONU
714 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
715 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000716 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000717 } else { //LockStateFSM already init
718 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000720 }
721 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000723 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000725 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
726 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000728 }
mpagenko01e726e2020-10-23 09:45:29 +0000729 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000730
731 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000732 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000733 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300734 }
735}
736
Himani Chawla6d2ae152020-09-02 13:11:20 +0530737//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
739 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000740
mpagenkofc4f56e2020-11-04 17:17:49 +0000741 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
742 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
743 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
744 // for real ONU's that should have nearly no influence
745 // Note that for real ONU's there is anyway a problematic situation with following sequence:
746 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
747 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
748 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
749 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
750
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000751 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000752 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000753 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000755 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000756 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000757 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000758 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300759}
760
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
762 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000763
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000765 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000767 return
768 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000770 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000772 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000773 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000774 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000775 dh.reconciling = false
776 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000777 }
Himani Chawla4d908332020-08-31 12:30:20 +0530778 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000779 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
780 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
781 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
782 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000783 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000784}
785
dbainbri4d3a0dc2020-12-02 00:33:42 +0000786func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
787 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000788
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000790 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 return
793 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 dh.pOnuTP.lockTpProcMutex()
795 defer dh.pOnuTP.unlockTpProcMutex()
796
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000797 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000799 log.Fields{"device-id": dh.deviceID})
800 dh.reconciling = false
801 return
802 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000803 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000804 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
805 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000807 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
808 dh.reconciling = false
809 return
810 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800811 for tpID := range uniData.PersTpPathMap {
812 // deadline context to ensure completion of background routines waited for
813 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
814 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000816
Girish Gowdra041dcb32020-11-16 16:54:30 -0800817 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
818 var wg sync.WaitGroup
819 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
821 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800822 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800824 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000826 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000828 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
829 dh.reconciling = false
830 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831 }
832}
833
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
835 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000840 return
841 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000842 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000844 log.Fields{"device-id": dh.deviceID})
845 dh.reconciling = false
846 return
847 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000848 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000849 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
850 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000852 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
853 dh.reconciling = false
854 return
855 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000856 var uniPort *onuUniPort
857 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000861 return
862 }
863 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000865 //the slice can be passed 'by value' here, - which internally passes its reference copy
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000866 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000868 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
869 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000874 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000875 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 }
878 }
879 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000880 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000882 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
883 dh.reconciling = false
884 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 }
886}
887
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
889 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 +0000890
891 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000892 dh.reconciling = false
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000893}
894
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
896 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000897
dbainbri4d3a0dc2020-12-02 00:33:42 +0000898 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000900 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000902 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000903 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000904 pDevEntry.lockOnuKVStoreMutex()
905 defer pDevEntry.unlockOnuKVStoreMutex()
906
907 // deadline context to ensure completion of background routines waited for
908 //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 +0530909 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000911
912 pDevEntry.resetKvProcessingErrorIndication()
913
914 var wg sync.WaitGroup
915 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000916 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
917 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000918
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000919 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000920 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000921}
922
dbainbri4d3a0dc2020-12-02 00:33:42 +0000923func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
924 logger.Debugw(ctx, "reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300925 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927 return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +0300928 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530930 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000931 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla4d908332020-08-31 12:30:20 +0530932 return err
933 }
mpagenko01e726e2020-10-23 09:45:29 +0000934
935 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000936 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000937
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000939 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000940 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300941 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000942 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300944 return err
945 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000946 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
ozgecanetsiae11479f2020-07-06 09:44:47 +0300947 return err
948 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000949 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000950 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
951 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
952 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
953 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300954 return nil
955}
956
mpagenkoc8bba412021-01-15 15:38:44 +0000957//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
958func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload) error {
959 logger.Warnw(ctx, "onuSwUpgrade not yet implemented in deviceHandler", log.Fields{
960 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko057889c2021-01-21 16:51:58 +0000961 //return success to comfort the core processing during integration
962 return nil
963 // TODO!!: also verify error response behavior
964 //return fmt.Errorf("onuSwUpgrade not yet implemented in deviceHandler: %s", dh.deviceID)
mpagenkoc8bba412021-01-15 15:38:44 +0000965}
966
Himani Chawla6d2ae152020-09-02 13:11:20 +0530967// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000968// #####################################################################################
969
970// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530971// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000972
dbainbri4d3a0dc2020-12-02 00:33:42 +0000973func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
974 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 +0000975}
976
977// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000979
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000981 var err error
982
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000983 // populate what we know. rest comes later after mib sync
984 dh.device.Root = false
985 dh.device.Vendor = "OpenONU"
986 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000987 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000988 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000989
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000990 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000991
992 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000993 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
994 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +0530995 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000996 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000997 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000998 log.Fields{"device-id": dh.deviceID})
999 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001000
Himani Chawla4d908332020-08-31 12:30:20 +05301001 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001002 dh.ponPortNumber = dh.device.ParentPortNo
1003
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001004 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1005 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1006 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001007 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001008 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301009 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001010
1011 /*
1012 self._pon = PonPort.create(self, self._pon_port_number)
1013 self._pon.add_peer(self.parent_id, self._pon_port_number)
1014 self.logger.debug('adding-pon-port-to-agent',
1015 type=self._pon.get_port().type,
1016 admin_state=self._pon.get_port().admin_state,
1017 oper_status=self._pon.get_port().oper_status,
1018 )
1019 */
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001020 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001022 var ponPortNo uint32 = 1
1023 if dh.ponPortNumber != 0 {
1024 ponPortNo = dh.ponPortNumber
1025 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001026
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001027 pPonPort := &voltha.Port{
1028 PortNo: ponPortNo,
1029 Label: fmt.Sprintf("pon-%d", ponPortNo),
1030 Type: voltha.Port_PON_ONU,
1031 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301032 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001033 PortNo: ponPortNo}}, // Peer port is parent's port number
1034 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001035 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1036 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001037 e.Cancel(err)
1038 return
1039 }
1040 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001041 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001042 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001043 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001044}
1045
1046// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001047func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001048
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001050 var err error
1051 /*
1052 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1053 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1054 return nil
1055 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001056 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1057 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001058 e.Cancel(err)
1059 return
1060 }
1061
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001062 if dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001063 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001064 // reconcilement will be continued after mib download is done
1065 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001066
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001067 /*
1068 ############################################################################
1069 # Setup Alarm handler
1070 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1071 device.serial_number)
1072 ############################################################################
1073 # Setup PM configuration for this device
1074 # Pass in ONU specific options
1075 kwargs = {
1076 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1077 'heartbeat': self.heartbeat,
1078 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1079 }
1080 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1081 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1082 self.logical_device_id, device.serial_number,
1083 grouped=True, freq_override=False, **kwargs)
1084 pm_config = self._pm_metrics.make_proto()
1085 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1086 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1087 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1088
1089 # Note, ONU ID and UNI intf set in add_uni_port method
1090 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1091 ani_ports=[self._pon])
1092
1093 # Code to Run OMCI Test Action
1094 kwargs_omci_test_action = {
1095 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1096 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1097 }
1098 serial_number = device.serial_number
1099 self._test_request = OmciTestRequest(self.core_proxy,
1100 self.omci_agent, self.device_id,
1101 AniG, serial_number,
1102 self.logical_device_id,
1103 exclusive=False,
1104 **kwargs_omci_test_action)
1105
1106 self.enabled = True
1107 else:
1108 self.logger.info('onu-already-activated')
1109 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001110
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001112}
1113
1114// doStateConnected get the device info and update to voltha core
1115// for comparison of the original method (not that easy to uncomment): compare here:
1116// voltha-openolt-adapter/adaptercore/device_handler.go
1117// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119
dbainbri4d3a0dc2020-12-02 00:33:42 +00001120 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301121 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001122 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001123 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001124}
1125
1126// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001127func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001128
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301130 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001131 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001132 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133
1134 /*
1135 // Synchronous call to update device state - this method is run in its own go routine
1136 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1137 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001138 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 +00001139 return err
1140 }
1141 return nil
1142 */
1143}
1144
1145// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001147
dbainbri4d3a0dc2020-12-02 00:33:42 +00001148 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001149 var err error
1150
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001151 device := dh.device
1152 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001153 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001155 e.Cancel(err)
1156 return
1157 }
1158
1159 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001160 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001161 /*
1162 // Update the all ports state on that device to disable
1163 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001164 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001165 return er
1166 }
1167
1168 //Update the device oper state and connection status
1169 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1170 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1171 dh.device = cloned
1172
1173 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001174 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001175 return er
1176 }
1177
1178 //get the child device for the parent device
1179 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1180 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001181 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001182 return err
1183 }
1184 for _, onuDevice := range onuDevices.Items {
1185
1186 // Update onu state as down in onu adapter
1187 onuInd := oop.OnuIndication{}
1188 onuInd.OperState = "down"
1189 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1190 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1191 if er != nil {
1192 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001193 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001194 //Do not return here and continue to process other ONUs
1195 }
1196 }
1197 // * Discovered ONUs entries need to be cleared , since after OLT
1198 // is up, it starts sending discovery indications again* /
1199 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001200 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001201 return nil
1202 */
Himani Chawla4d908332020-08-31 12:30:20 +05301203 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001204 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001206}
1207
Himani Chawla6d2ae152020-09-02 13:11:20 +05301208// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001209// #################################################################################
1210
1211// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301212// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001213
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001214//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001215func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001216 dh.lockDevice.RLock()
1217 pOnuDeviceEntry := dh.pOnuOmciDevice
1218 if aWait && pOnuDeviceEntry == nil {
1219 //keep the read sema short to allow for subsequent write
1220 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001221 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001222 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1223 // so it might be needed to wait here for that event with some timeout
1224 select {
1225 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001227 return nil
1228 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001229 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001230 // if written now, we can return the written value without sema
1231 return dh.pOnuOmciDevice
1232 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001233 }
mpagenko3af1f032020-06-10 08:53:41 +00001234 dh.lockDevice.RUnlock()
1235 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001236}
1237
Himani Chawla6d2ae152020-09-02 13:11:20 +05301238//setOnuDeviceEntry sets the ONU device entry within the handler
1239func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdrae09a6202021-01-12 18:10:59 -08001240 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001241 dh.lockDevice.Lock()
1242 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001243 dh.pOnuOmciDevice = apDeviceEntry
1244 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001245 dh.pOnuMetricsMgr = apOnuMetricsMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001246}
1247
Himani Chawla6d2ae152020-09-02 13:11:20 +05301248//addOnuDeviceEntry creates a new ONU device or returns the existing
1249func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001251
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001253 if deviceEntry == nil {
1254 /* costum_me_map in python code seems always to be None,
1255 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1256 /* also no 'clock' argument - usage open ...*/
1257 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001258 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001259 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001260 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001261 //error treatment possible //TODO!!!
Girish Gowdrae09a6202021-01-12 18:10:59 -08001262 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr)
mpagenko3af1f032020-06-10 08:53:41 +00001263 // fire deviceEntry ready event to spread to possibly waiting processing
1264 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001266 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001268 }
1269 // might be updated with some error handling !!!
1270 return nil
1271}
1272
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1274 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001275 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1276
1277 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001278
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001280 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001282 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1283 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001284 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 if err := dh.storePersistentData(ctx); err != nil {
1286 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001287 log.Fields{"device-id": dh.deviceID, "err": err})
1288 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001289 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001290 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001291 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001292 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1293 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001294 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001295 }
1296 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001297 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001298 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001299
1300 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001301 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 +00001302 log.Fields{"device-id": dh.deviceID})
1303 dh.reconciling = false
1304 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001305 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001306 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1307 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1308 // 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 +00001309 // 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 +00001310 // so let's just try to keep it simple ...
1311 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001312 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001313 if err != nil || device == nil {
1314 //TODO: needs to handle error scenarios
1315 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1316 return errors.New("Voltha Device not found")
1317 }
1318 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001319
dbainbri4d3a0dc2020-12-02 00:33:42 +00001320 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001321 return err
mpagenko3af1f032020-06-10 08:53:41 +00001322 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001323
dbainbri4d3a0dc2020-12-02 00:33:42 +00001324 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.reconciling)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001325
1326 /* this might be a good time for Omci Verify message? */
1327 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001328 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001329 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001330 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001331 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001332
1333 /* give the handler some time here to wait for the OMCi verification result
1334 after Timeout start and try MibUpload FSM anyway
1335 (to prevent stopping on just not supported OMCI verification from ONU) */
1336 select {
1337 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001338 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001339 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001341 }
1342
1343 /* In py code it looks earlier (on activate ..)
1344 # Code to Run OMCI Test Action
1345 kwargs_omci_test_action = {
1346 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1347 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1348 }
1349 serial_number = device.serial_number
1350 self._test_request = OmciTestRequest(self.core_proxy,
1351 self.omci_agent, self.device_id,
1352 AniG, serial_number,
1353 self.logical_device_id,
1354 exclusive=False,
1355 **kwargs_omci_test_action)
1356 ...
1357 # Start test requests after a brief pause
1358 if not self._test_request_started:
1359 self._test_request_started = True
1360 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1361 reactor.callLater(tststart, self._test_request.start_collector)
1362
1363 */
1364 /* which is then: in omci_test_request.py : */
1365 /*
1366 def start_collector(self, callback=None):
1367 """
1368 Start the collection loop for an adapter if the frequency > 0
1369
1370 :param callback: (callable) Function to call to collect PM data
1371 """
1372 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1373 if callback is None:
1374 callback = self.perform_test_omci
1375
1376 if self.lc is None:
1377 self.lc = LoopingCall(callback)
1378
1379 if self.default_freq > 0:
1380 self.lc.start(interval=self.default_freq / 10)
1381
1382 def perform_test_omci(self):
1383 """
1384 Perform the initial test request
1385 """
1386 ani_g_entities = self._device.configuration.ani_g_entities
1387 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1388 is not None else None
1389 self._entity_id = ani_g_entities_ids[0]
1390 self.logger.info('perform-test', entity_class=self._entity_class,
1391 entity_id=self._entity_id)
1392 try:
1393 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1394 result = yield self._device.omci_cc.send(frame)
1395 if not result.fields['omci_message'].fields['success_code']:
1396 self.logger.info('Self-Test Submitted Successfully',
1397 code=result.fields[
1398 'omci_message'].fields['success_code'])
1399 else:
1400 raise TestFailure('Test Failure: {}'.format(
1401 result.fields['omci_message'].fields['success_code']))
1402 except TimeoutError as e:
1403 self.deferred.errback(failure.Failure(e))
1404
1405 except Exception as e:
1406 self.logger.exception('perform-test-Error', e=e,
1407 class_id=self._entity_class,
1408 entity_id=self._entity_id)
1409 self.deferred.errback(failure.Failure(e))
1410
1411 */
1412
1413 // PM related heartbeat??? !!!TODO....
1414 //self._heartbeat.enabled = True
1415
mpagenko1cc3cb42020-07-27 15:24:38 +00001416 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1417 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1418 * 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 +05301419 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001420 */
1421 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001422 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001423 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001424 if pMibUlFsm.Is(ulStDisabled) {
1425 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 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 +00001427 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301428 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301430 //Determine ONU status and start/re-start MIB Synchronization tasks
1431 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001432 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301433 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001434 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 +00001435 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001436 }
Himani Chawla4d908332020-08-31 12:30:20 +05301437 } else {
1438 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 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 +00001440 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301441 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001442 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001443 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001444 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001446 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001447 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001448 }
1449 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001450 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001451 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001453
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001454 if !dh.getCollectorIsRunning() {
1455 // Start PM collector routine
1456 go dh.startCollector(ctx)
1457 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001458 return nil
1459}
1460
dbainbri4d3a0dc2020-12-02 00:33:42 +00001461func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001462 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001463 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001464 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001466
mpagenko900ee4b2020-10-12 11:56:34 +00001467 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1468 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1469 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001470 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001471 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001472 log.Fields{"device-id": dh.deviceID, "error": err})
1473 // abort: system behavior is just unstable ...
1474 return err
1475 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001476 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001477 _ = 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 +00001478
1479 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1480 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1481 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001483 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001485 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001486 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001488
1489 //TODO!!! remove existing traffic profiles
1490 /* from py code, if TP's exist, remove them - not yet implemented
1491 self._tp = dict()
1492 # Let TP download happen again
1493 for uni_id in self._tp_service_specific_task:
1494 self._tp_service_specific_task[uni_id].clear()
1495 for uni_id in self._tech_profile_download_done:
1496 self._tech_profile_download_done[uni_id].clear()
1497 */
1498
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001500
mpagenkofc4f56e2020-11-04 17:17:49 +00001501 dh.ReadyForSpecificOmciConfig = false
1502
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001504 // abort: system behavior is just unstable ...
1505 return err
1506 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001508 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001510 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001511 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001512 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001513 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001514 // abort: system behavior is just unstable ...
1515 return err
1516 }
1517 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001519 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001520 return nil
1521}
1522
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001523func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001524 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1525 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1526 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1527 // and using the stop/reset event should never harm
1528
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001530 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001532 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1533 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001534 if includingMibSyncFsm {
1535 //the MibSync FSM might be active all the ONU-active time,
1536 // hence it must be stopped unconditionally
1537 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1538 if pMibUlFsm != nil {
1539 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1540 }
mpagenko900ee4b2020-10-12 11:56:34 +00001541 }
1542 //MibDownload may run
1543 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1544 if pMibDlFsm != nil {
1545 _ = pMibDlFsm.Event(dlEvReset)
1546 }
1547 //port lock/unlock FSM's may be active
1548 if dh.pUnlockStateFsm != nil {
1549 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1550 }
1551 if dh.pLockStateFsm != nil {
1552 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1553 }
1554 //techProfile related PonAniConfigFsm FSM may be active
1555 if dh.pOnuTP != nil {
1556 // should always be the case here
1557 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1558 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001559 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1560 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1561 }
mpagenko900ee4b2020-10-12 11:56:34 +00001562 }
1563 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001564 // reset the possibly existing VlanConfigFsm
1565 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1566 //VlanFilterFsm exists and was already started
1567 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1568 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001569 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001570 // no need to remove specific data
1571 pVlanFilterFsm.RequestClearPersistency(false)
1572 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001573 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1574 }
1575 }
1576 }
1577 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001578 if dh.getCollectorIsRunning() {
1579 // Stop collector routine
1580 dh.stopCollector <- true
1581 }
mpagenko900ee4b2020-10-12 11:56:34 +00001582 return nil
1583}
1584
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1586 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 +05301587
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.reconciling)
1589 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001590 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001591 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001592 return
1593 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001594 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001595 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1596 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1597 for _, mgmtEntityID := range pptpInstKeys {
1598 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1599 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301601 i++
1602 }
1603 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301605 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001606 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1607 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301608 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001609 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301610 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301612 i++
1613 }
1614 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301616 }
1617 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301619 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001620 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1621 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1622 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1623 * disable/enable toggling here to allow traffic
1624 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1625 * like the py comment says:
1626 * # start by locking all the unis till mib sync and initial mib is downloaded
1627 * # this way we can capture the port down/up events when we are ready
1628 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301629
mpagenkoa40e99a2020-11-17 13:50:39 +00001630 // Init Uni Ports to Admin locked state
1631 // *** should generate UniLockStateDone event *****
1632 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001634 } else { //LockStateFSM already init
1635 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001637 }
1638}
1639
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1641 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301642 /* Mib download procedure -
1643 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1644 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001646 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001648 return
1649 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301650 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1651 if pMibDlFsm != nil {
1652 if pMibDlFsm.Is(dlStDisabled) {
1653 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 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 +05301655 // maybe try a FSM reset and then again ... - TODO!!!
1656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301658 // maybe use more specific states here for the specific download steps ...
1659 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301661 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301663 //Begin MIB data download (running autonomously)
1664 }
1665 }
1666 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001668 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301669 // maybe try a FSM reset and then again ... - TODO!!!
1670 }
1671 /***** Mib download started */
1672 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001673 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301674 }
1675}
1676
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1678 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301679 //initiate DevStateUpdate
1680 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001682 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301684 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1685 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301687 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001688 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301689 }
1690 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001692 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694 return
1695 }
1696 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 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 +00001698 log.Fields{"device-id": dh.deviceID})
1699 dh.reconciling = false
1700 return
1701 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301703 log.Fields{"device-id": dh.deviceID})
1704 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.reconciling)
mpagenkofc4f56e2020-11-04 17:17:49 +00001706 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301707 // *** should generate UniUnlockStateDone event *****
1708 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301710 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301711 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301713 }
1714}
1715
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1717 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301718
1719 if !dh.reconciling {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301721 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1723 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726 return
1727 }
1728 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 if err := dh.storePersistentData(ctx); err != nil {
1730 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001731 log.Fields{"device-id": dh.deviceID, "err": err})
1732 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301733 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734 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 +05301735 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001737 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301738 }
1739}
1740
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1742 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001743 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001745 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1746 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001748 }
1749
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001751 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001753
1754 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001756
dbainbri4d3a0dc2020-12-02 00:33:42 +00001757 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001758 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001760 return
1761 }
1762 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001763 if err := dh.storePersistentData(ctx); err != nil {
1764 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001765 log.Fields{"device-id": dh.deviceID, "err": err})
1766 }
mpagenko900ee4b2020-10-12 11:56:34 +00001767}
1768
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1770 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001771 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001773 voltha.OperStatus_ACTIVE); err != nil {
1774 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001775 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001776 }
1777
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001779 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001780 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001782
1783 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001785
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001787 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001789 return
1790 }
1791 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792 if err := dh.storePersistentData(ctx); err != nil {
1793 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001794 log.Fields{"device-id": dh.deviceID, "err": err})
1795 }
mpagenko900ee4b2020-10-12 11:56:34 +00001796}
1797
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001799 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001801 // attention: the device reason update is done based on ONU-UNI-Port related activity
1802 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001803 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001804 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
dbainbri