blob: 6c4d5ce1b94c22c89844380488ae989fa80da4b4 [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"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
28 "github.com/gogo/protobuf/proto"
29 "github.com/golang/protobuf/ptypes"
30 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000031 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
33 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053034 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000035 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
36 "github.com/opencord/voltha-lib-go/v4/pkg/log"
37 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050038 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
40 "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v4/go/openolt"
44 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
47/*
48// Constants for number of retries and for timeout
49const (
50 MaxRetry = 10
51 MaxTimeOutInMs = 500
52)
53*/
54
mpagenko1cc3cb42020-07-27 15:24:38 +000055const (
56 // events of Device FSM
57 devEvDeviceInit = "devEvDeviceInit"
58 devEvGrpcConnected = "devEvGrpcConnected"
59 devEvGrpcDisconnected = "devEvGrpcDisconnected"
60 devEvDeviceUpInd = "devEvDeviceUpInd"
61 devEvDeviceDownInd = "devEvDeviceDownInd"
62)
63const (
64 // states of Device FSM
65 devStNull = "devStNull"
66 devStDown = "devStDown"
67 devStInit = "devStInit"
68 devStConnected = "devStConnected"
69 devStUp = "devStUp"
70)
71
Holger Hildebrandt24d51952020-05-04 14:03:42 +000072//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
73const (
Himani Chawla4d908332020-08-31 12:30:20 +053074 pon = voltha.EventSubCategory_PON
75 //olt = voltha.EventSubCategory_OLT
76 //ont = voltha.EventSubCategory_ONT
77 //onu = voltha.EventSubCategory_ONU
78 //nni = voltha.EventSubCategory_NNI
79 //service = voltha.EventCategory_SERVICE
80 //security = voltha.EventCategory_SECURITY
81 equipment = voltha.EventCategory_EQUIPMENT
82 //processing = voltha.EventCategory_PROCESSING
83 //environment = voltha.EventCategory_ENVIRONMENT
84 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085)
86
87const (
88 cEventObjectType = "ONU"
89)
90const (
91 cOnuActivatedEvent = "ONU_ACTIVATED"
92)
93
Holger Hildebrandt10d98192021-01-27 15:29:31 +000094type usedOmciConfigFsms int
95
96const (
97 cUploadFsm usedOmciConfigFsms = iota
98 cDownloadFsm
99 cUniLockFsm
100 cUniUnLockFsm
101 cAniConfigFsm
102 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800103 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000104 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105)
106
mpagenkof1fc3862021-02-16 10:09:52 +0000107type omciIdleCheckStruct struct {
108 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
109 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000110}
111
mpagenkof1fc3862021-02-16 10:09:52 +0000112var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
113 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
114 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
115 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
117 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
118 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
119 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000120 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000123const (
124 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000125 drUnset = 0
126 drActivatingOnu = 1
127 drStartingOpenomci = 2
128 drDiscoveryMibsyncComplete = 3
129 drInitialMibDownloaded = 4
130 drTechProfileConfigDownloadSuccess = 5
131 drOmciFlowsPushed = 6
132 drOmciAdminLock = 7
133 drOnuReenabled = 8
134 drStoppingOpenomci = 9
135 drRebooting = 10
136 drOmciFlowsDeleted = 11
137 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000138)
139
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000140var deviceReasonMap = map[uint8]string{
141 drUnset: "unset",
142 drActivatingOnu: "activating-onu",
143 drStartingOpenomci: "starting-openomci",
144 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
145 drInitialMibDownloaded: "initial-mib-downloaded",
146 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
147 drOmciFlowsPushed: "omci-flows-pushed",
148 drOmciAdminLock: "omci-admin-lock",
149 drOnuReenabled: "onu-reenabled",
150 drStoppingOpenomci: "stopping-openomci",
151 drRebooting: "rebooting",
152 drOmciFlowsDeleted: "omci-flows-deleted",
153 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
154}
155
Himani Chawla6d2ae152020-09-02 13:11:20 +0530156//deviceHandler will interact with the ONU ? device.
157type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000158 deviceID string
159 DeviceType string
160 adminState string
161 device *voltha.Device
162 logicalDeviceID string
163 ProxyAddressID string
164 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530165 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000166 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000167
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000168 coreProxy adapterif.CoreProxy
169 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530170 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000171
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800172 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800173
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000174 pOpenOnuAc *OpenONUAC
175 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530176 //pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000177 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000178 pOnuOmciDevice *OnuDeviceEntry
Himani Chawla6d2ae152020-09-02 13:11:20 +0530179 pOnuTP *onuUniTechProf
Girish Gowdrae09a6202021-01-12 18:10:59 -0800180 pOnuMetricsMgr *onuMetricsManager
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530181 pAlarmMgr *onuAlarmManager
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000182 exitChannel chan int
183 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000184 pOnuIndication *oop.OnuIndication
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000185 deviceReason uint8
Himani Chawla6d2ae152020-09-02 13:11:20 +0530186 pLockStateFsm *lockStateFsm
187 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000188
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000189 //flowMgr *OpenOltFlowMgr
190 //eventMgr *OpenOltEventMgr
191 //resourceMgr *rsrcMgr.OpenOltResourceMgr
192
193 //discOnus sync.Map
194 //onus sync.Map
195 //portStats *OpenOltStatisticsMgr
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000196 collectorIsRunning bool
197 mutexCollectorFlag sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000198 stopCollector chan bool
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530199 alarmManagerIsRunning bool
200 mutextAlarmManagerFlag sync.RWMutex
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530201 stopAlarmManager chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000202 stopHeartbeatCheck chan bool
mpagenkofc4f56e2020-11-04 17:17:49 +0000203 uniEntityMap map[uint32]*onuUniPort
mpagenkof1fc3862021-02-16 10:09:52 +0000204 mutexKvStoreContext sync.Mutex
205 lockVlanConfig sync.RWMutex
mpagenkofc4f56e2020-11-04 17:17:49 +0000206 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
mpagenko80622a52021-02-09 16:53:23 +0000207 lockUpgradeFsm sync.RWMutex
208 pOnuUpradeFsm *OnuUpgradeFsm
mpagenkofc4f56e2020-11-04 17:17:49 +0000209 reconciling bool
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000210 mutexReconcilingFlag sync.RWMutex
211 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
mpagenkofc4f56e2020-11-04 17:17:49 +0000212 ReadyForSpecificOmciConfig bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000213}
214
Himani Chawla6d2ae152020-09-02 13:11:20 +0530215//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530216func 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 +0530217 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000218 dh.coreProxy = cp
219 dh.AdapterProxy = ap
220 dh.EventProxy = ep
221 cloned := (proto.Clone(device)).(*voltha.Device)
222 dh.deviceID = cloned.Id
223 dh.DeviceType = cloned.Type
224 dh.adminState = "up"
225 dh.device = cloned
226 dh.pOpenOnuAc = adapter
227 dh.exitChannel = make(chan int, 1)
228 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000229 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000230 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000231 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530232 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530233 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000234 dh.stopHeartbeatCheck = make(chan bool, 2)
235 //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 +0000236 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530237 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000238 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000239 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000240 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000241 dh.reconciling = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000242 dh.chReconcilingFinished = make(chan bool)
mpagenkofc4f56e2020-11-04 17:17:49 +0000243 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800245 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
246 dh.pmConfigs = cloned.PmConfigs
247 } /* else {
248 // will be populated when onu_metrics_mananger is initialized.
249 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800250
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 // Device related state machine
252 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000253 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000255 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
256 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
257 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
258 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
259 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000260 },
261 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000262 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
263 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
264 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
265 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
266 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
267 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
268 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
269 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 },
271 )
mpagenkoaf801632020-07-03 10:00:42 +0000272
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000273 return &dh
274}
275
Himani Chawla6d2ae152020-09-02 13:11:20 +0530276// start save the device to the data model
277func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000278 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281}
282
Himani Chawla4d908332020-08-31 12:30:20 +0530283/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530285func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 logger.Debug("stopping-device-handler")
287 dh.exitChannel <- 1
288}
Himani Chawla4d908332020-08-31 12:30:20 +0530289*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290
291// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530292// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293
Girish Gowdrae0140f02021-02-02 16:55:09 -0800294//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530295func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000299 if dh.pDeviceStateFsm.Is(devStNull) {
300 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000301 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000303 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800304 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
305 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800306 // Now, set the initial PM configuration for that device
307 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
308 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
309 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800310 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313 }
314
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315}
316
mpagenko057889c2021-01-21 16:51:58 +0000317func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530318 msgBody := msg.GetBody()
319 omciMsg := &ic.InterAdapterOmciMessage{}
320 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530322 "device-id": dh.deviceID, "error": err})
323 return err
324 }
325
mpagenko80622a52021-02-09 16:53:23 +0000326 /* msg print moved symmetrically to omci_cc, if wanted here as additional debug, than perhaps only based on additional debug setting!
Himani Chawla26e555c2020-08-31 12:30:20 +0530327 //assuming omci message content is hex coded!
328 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530330 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000331 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530333 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000334 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000335 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000336 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000337 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 +0530338 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000340 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530341}
342
Himani Chawla6d2ae152020-09-02 13:11:20 +0530343func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530345 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000346
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000348
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000350 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000351 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000352 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
353 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 if dh.pOnuTP == nil {
355 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000358 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530359 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000360 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000362 "device-state": deviceReasonMap[dh.deviceReason]})
363 return fmt.Errorf("improper device state %s on device %s", deviceReasonMap[dh.deviceReason], dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530364 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000365 //previous state test here was just this one, now extended for more states to reject the SetRequest:
366 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
367 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530368
369 msgBody := msg.GetBody()
370 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
371 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000372 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 "device-id": dh.deviceID, "error": err})
374 return err
375 }
376
377 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000378 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
379 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000381 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382
383 if techProfMsg.UniId > 255 {
384 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
385 techProfMsg.UniId, dh.deviceID))
386 }
387 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800388 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
389 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800391 return err
392 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393
dbainbri4d3a0dc2020-12-02 00:33:42 +0000394 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 // if there has been some change for some uni TechProfilePath
396 //in order to allow concurrent calls to other dh instances we do not wait for execution here
397 //but doing so we can not indicate problems to the caller (who does what with that then?)
398 //by now we just assume straightforward successful execution
399 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
400 // possible problems to the caller later autonomously
401
402 // deadline context to ensure completion of background routines waited for
403 //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 +0530404 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 dctx, cancel := context.WithDeadline(context.Background(), deadline)
406
Girish Gowdra041dcb32020-11-16 16:54:30 -0800407 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408 pDevEntry.resetKvProcessingErrorIndication()
409
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 var wg sync.WaitGroup
411 wg.Add(2) // for the 2 go routines to finish
412 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000413 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
414 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
415 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000416
Girish Gowdra041dcb32020-11-16 16:54:30 -0800417 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530418 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000419 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530420 return nil
421}
422
Himani Chawla6d2ae152020-09-02 13:11:20 +0530423func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000424 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 msg *ic.InterAdapterMessage) error {
426
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000428
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000430 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000431 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000432 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
433 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530434 if dh.pOnuTP == nil {
435 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000436 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530437 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000438 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530439 }
440
441 msgBody := msg.GetBody()
442 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
443 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530445 "device-id": dh.deviceID, "error": err})
446 return err
447 }
448
449 //compare TECH_PROFILE_DOWNLOAD_REQUEST
450 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000451 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530452
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453 if delGemPortMsg.UniId > 255 {
454 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
455 delGemPortMsg.UniId, dh.deviceID))
456 }
457 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800458 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
459 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000460 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 -0800461 return err
462 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530463
mpagenkofc4f56e2020-11-04 17:17:49 +0000464 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000465
mpagenkofc4f56e2020-11-04 17:17:49 +0000466 // deadline context to ensure completion of background routines waited for
467 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
468 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469
Girish Gowdra041dcb32020-11-16 16:54:30 -0800470 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000471
mpagenkofc4f56e2020-11-04 17:17:49 +0000472 var wg sync.WaitGroup
473 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000474 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000475 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000477
Girish Gowdra041dcb32020-11-16 16:54:30 -0800478 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530479}
480
Himani Chawla6d2ae152020-09-02 13:11:20 +0530481func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000482 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484
dbainbri4d3a0dc2020-12-02 00:33:42 +0000485 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000486
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000488 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000490 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
491 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 if dh.pOnuTP == nil {
493 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000494 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530495 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000496 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530497 }
498
499 msgBody := msg.GetBody()
500 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
501 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000502 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530503 "device-id": dh.deviceID, "error": err})
504 return err
505 }
506
507 //compare TECH_PROFILE_DOWNLOAD_REQUEST
508 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000510
511 if delTcontMsg.UniId > 255 {
512 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
513 delTcontMsg.UniId, dh.deviceID))
514 }
515 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800516 tpPath := delTcontMsg.TpPath
517 tpID, err := GetTpIDFromTpPath(tpPath)
518 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800520 return err
521 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522
dbainbri4d3a0dc2020-12-02 00:33:42 +0000523 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530525 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530526 dctx, cancel := context.WithDeadline(context.Background(), deadline)
527
Girish Gowdra041dcb32020-11-16 16:54:30 -0800528 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000529 pDevEntry.resetKvProcessingErrorIndication()
530
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 var wg sync.WaitGroup
532 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 cResourceTcont, delTcontMsg.AllocId, &wg)
535 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
537 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000538
Girish Gowdra041dcb32020-11-16 16:54:30 -0800539 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530540 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 return nil
542}
543
Himani Chawla6d2ae152020-09-02 13:11:20 +0530544//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000545// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
546// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000548 msgID := msg.Header.Id
549 msgType := msg.Header.Type
550 fromTopic := msg.Header.FromTopic
551 toTopic := msg.Header.ToTopic
552 toDeviceID := msg.Header.ToDeviceId
553 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000554 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000555 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
556
557 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000558 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000559 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
560 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000561 {
mpagenko057889c2021-01-21 16:51:58 +0000562 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000563 }
mpagenkoaf801632020-07-03 10:00:42 +0000564 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
565 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000566 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000567 }
568 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
569 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000570 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000571
mpagenkoaf801632020-07-03 10:00:42 +0000572 }
573 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
574 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000575 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000576 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000577 default:
578 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000579 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000580 "msgType": msg.Header.Type, "device-id": dh.deviceID})
581 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000582 }
583 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000584}
585
mpagenkodff5dda2020-08-28 11:52:01 +0000586//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
588 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000589 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000591
mpagenko01e726e2020-10-23 09:45:29 +0000592 var retError error = nil
593 //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 +0000594 if apOfFlowChanges.ToRemove != nil {
595 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000596 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000598 "device-id": dh.deviceID})
599 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000600 continue
601 }
602 flowInPort := flow.GetInPort(flowItem)
603 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604 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 +0000605 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
606 continue
607 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000608 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000609 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000610 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000611 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000612 continue
613 } else {
614 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530615 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000616 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
617 loUniPort = uniPort
618 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000620 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
621 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
622 flowInPort, dh.deviceID)
623 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000624 }
625 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000627 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000628 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000630 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000631 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000633 log.Fields{"device-id": dh.deviceID, "error": err})
634 retError = err
635 continue
636 //return err
637 } else { // if last setting succeeds, overwrite possibly previously set error
638 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000639 }
640 }
641 }
642 }
mpagenko01e726e2020-10-23 09:45:29 +0000643 if apOfFlowChanges.ToAdd != nil {
644 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
645 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000647 "device-id": dh.deviceID})
648 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
649 continue
650 }
651 flowInPort := flow.GetInPort(flowItem)
652 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 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 +0000654 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
655 continue
656 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
657 } else if flowInPort == dh.ponPortNumber {
658 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000660 "device-id": dh.deviceID, "inPort": flowInPort})
661 continue
662 } else {
663 // this is the relevant upstream flow
664 var loUniPort *onuUniPort
665 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
666 loUniPort = uniPort
667 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000669 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
670 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
671 flowInPort, dh.deviceID)
672 continue
673 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
674 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
676 // if not, we just throw some error here to have an indication about that, if we really need to support that
677 // then we would need to create some means to activate the internal stored flows
678 // after the device gets active automatically (and still with its dependency to the TechProfile)
679 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
680 // also abort for the other still possible flows here
681 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000683 "last device-reason": deviceReasonMap[dh.deviceReason]})
mpagenkofc4f56e2020-11-04 17:17:49 +0000684 return fmt.Errorf("improper device state on device %s", dh.deviceID)
685 }
686
mpagenko01e726e2020-10-23 09:45:29 +0000687 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000689 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
690 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000691 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000692 //try next flow after processing error
693 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000695 log.Fields{"device-id": dh.deviceID, "error": err})
696 retError = err
697 continue
698 //return err
699 } else { // if last setting succeeds, overwrite possibly previously set error
700 retError = nil
701 }
702 }
703 }
704 }
705 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000706}
707
Himani Chawla6d2ae152020-09-02 13:11:20 +0530708//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000709//following are the expected device states after this activity:
710//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
711// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
713 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000714
mpagenko900ee4b2020-10-12 11:56:34 +0000715 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000716 //note that disableDevice sequences in some 'ONU active' state may yield also
717 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000718 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000719 if dh.deviceReason != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000720 //disable-device shall be just a UNi/ONU-G related admin state setting
721 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000722
mpagenkofc4f56e2020-11-04 17:17:49 +0000723 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000724 // disable UNI ports/ONU
725 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
726 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000728 } else { //LockStateFSM already init
729 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000731 }
732 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000734 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000736 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
737 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000738 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000739 }
mpagenko01e726e2020-10-23 09:45:29 +0000740 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000741
742 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000744 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300745 }
746}
747
Himani Chawla6d2ae152020-09-02 13:11:20 +0530748//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000749func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
750 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000751
mpagenkofc4f56e2020-11-04 17:17:49 +0000752 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
753 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
754 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
755 // for real ONU's that should have nearly no influence
756 // Note that for real ONU's there is anyway a problematic situation with following sequence:
757 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
758 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
759 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
760 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
761
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000762 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000763 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000764 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000766 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000767 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000769 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300770}
771
dbainbri4d3a0dc2020-12-02 00:33:42 +0000772func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
773 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000774
dbainbri4d3a0dc2020-12-02 00:33:42 +0000775 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000776 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000777 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000778 return
779 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000781 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000783 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000785 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000786 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000787 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000788 }
Himani Chawla4d908332020-08-31 12:30:20 +0530789 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000790 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
791 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
792 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
793 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000795}
796
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
798 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000799
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000801 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000803 return
804 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000805 dh.pOnuTP.lockTpProcMutex()
806 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000807 pDevEntry.persUniConfigMutex.RLock()
808 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000809
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000810 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000811 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000812 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000813 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000814 return
815 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000816 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000817 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
818 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000820 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000821 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000822 return
823 }
Girish Gowdra041dcb32020-11-16 16:54:30 -0800824 for tpID := range uniData.PersTpPathMap {
825 // deadline context to ensure completion of background routines waited for
826 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
827 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000828 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000829
Girish Gowdra041dcb32020-11-16 16:54:30 -0800830 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
831 var wg sync.WaitGroup
832 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
834 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800835 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800837 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000838 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000839 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000841 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000842 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000843 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000844 }
845}
846
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
848 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000849
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000851 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000853 return
854 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000855 pDevEntry.persUniConfigMutex.RLock()
856 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000857 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000859 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000860 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000861 return
862 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000864 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
865 if len(uniData.PersFlowParams) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000867 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000868 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000869 return
870 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 var uniPort *onuUniPort
872 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000873 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 logger.Errorw(ctx, "onuUniPort data not found!", log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 return
877 }
878 for _, flowData := range uniData.PersFlowParams {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000879 logger.Debugw(ctx, "add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000880 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000881 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000882 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000884 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
885 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887 }
mpagenkof1fc3862021-02-16 10:09:52 +0000888 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000889 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000890 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000892 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000893 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000894 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000895 }
896 }
897 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000898 if len(uniData.PersTpPathMap) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000899 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000900 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000901 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000902 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903 }
904}
905
dbainbri4d3a0dc2020-12-02 00:33:42 +0000906func (dh *deviceHandler) reconcileMetrics(ctx context.Context) {
907 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 +0000908
909 //TODO: reset of reconciling-flag has always to be done in the last reconcile*() function
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000910 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000911}
912
dbainbri4d3a0dc2020-12-02 00:33:42 +0000913func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
914 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000915
dbainbri4d3a0dc2020-12-02 00:33:42 +0000916 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000917 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000918 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000919 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000920 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000921 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000922
923 // deadline context to ensure completion of background routines waited for
924 //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 +0530925 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000926 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927
928 pDevEntry.resetKvProcessingErrorIndication()
929
930 var wg sync.WaitGroup
931 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000932 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
933 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000934
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000935 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000936 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000937}
938
mpagenko15ff4a52021-03-02 10:09:20 +0000939//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
940// before this change here return like this was used:
941// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
942//was and is called in background - error return does not make sense
943func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
944 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
945 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000946 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +0000947 return
ozgecanetsiae11479f2020-07-06 09:44:47 +0300948 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +0530950 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000951 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +0000952 return
Himani Chawla4d908332020-08-31 12:30:20 +0530953 }
mpagenko01e726e2020-10-23 09:45:29 +0000954
955 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +0000956 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +0000957
dbainbri4d3a0dc2020-12-02 00:33:42 +0000958 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +0000959 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000960 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +0300961 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000962 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +0000964 return
ozgecanetsiae11479f2020-07-06 09:44:47 +0300965 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000967 return
ozgecanetsiae11479f2020-07-06 09:44:47 +0300968 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000969 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +0000970 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
971 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
972 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
973 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +0300974}
975
mpagenkoc8bba412021-01-15 15:38:44 +0000976//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +0000977func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
978 apDownloadManager *adapterDownloadManager) error {
979 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +0000980 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +0000981
982 var err error
mpagenko15ff4a52021-03-02 10:09:20 +0000983 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
984 if pDevEntry == nil {
985 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
986 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
987 }
988
mpagenko80622a52021-02-09 16:53:23 +0000989 if dh.ReadyForSpecificOmciConfig {
mpagenko15ff4a52021-03-02 10:09:20 +0000990 var inactiveImageID uint16
991 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
992 dh.lockUpgradeFsm.Lock()
993 defer dh.lockUpgradeFsm.Unlock()
994 if dh.pOnuUpradeFsm == nil {
995 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
996 if err == nil {
997 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
998 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
999 "device-id": dh.deviceID, "error": err})
1000 }
1001 } else {
1002 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001003 "device-id": dh.deviceID, "error": err})
1004 }
mpagenko15ff4a52021-03-02 10:09:20 +00001005 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1006 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1007 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1008 if pUpgradeStatemachine != nil {
1009 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1010 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1011 "device-id": dh.deviceID, "error": err})
1012 }
1013 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1014 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1015 // for now a second start of download should work again
1016 } else { //should never occur
1017 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1018 "device-id": dh.deviceID})
1019 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001020 }
mpagenko80622a52021-02-09 16:53:23 +00001021 }
mpagenko15ff4a52021-03-02 10:09:20 +00001022 } else {
1023 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1024 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001025 }
1026 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001027 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1028 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001029 }
1030 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001031}
1032
Himani Chawla6d2ae152020-09-02 13:11:20 +05301033// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001034// #####################################################################################
1035
1036// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301037// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001038
dbainbri4d3a0dc2020-12-02 00:33:42 +00001039func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1040 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 +00001041}
1042
1043// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001045
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001047 var err error
1048
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001049 // populate what we know. rest comes later after mib sync
1050 dh.device.Root = false
1051 dh.device.Vendor = "OpenONU"
1052 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001053 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001054 dh.deviceReason = drActivatingOnu
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001055
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001056 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001057
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001058 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001059 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1060 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301061 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001062 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001063 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001064 log.Fields{"device-id": dh.deviceID})
1065 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001066
Himani Chawla4d908332020-08-31 12:30:20 +05301067 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001068 dh.ponPortNumber = dh.device.ParentPortNo
1069
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001070 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1071 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1072 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001074 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301075 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001076
1077 /*
1078 self._pon = PonPort.create(self, self._pon_port_number)
1079 self._pon.add_peer(self.parent_id, self._pon_port_number)
1080 self.logger.debug('adding-pon-port-to-agent',
1081 type=self._pon.get_port().type,
1082 admin_state=self._pon.get_port().admin_state,
1083 oper_status=self._pon.get_port().oper_status,
1084 )
1085 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001086 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001087 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001088 var ponPortNo uint32 = 1
1089 if dh.ponPortNumber != 0 {
1090 ponPortNo = dh.ponPortNumber
1091 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001092
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001093 pPonPort := &voltha.Port{
1094 PortNo: ponPortNo,
1095 Label: fmt.Sprintf("pon-%d", ponPortNo),
1096 Type: voltha.Port_PON_ONU,
1097 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301098 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001099 PortNo: ponPortNo}}, // Peer port is parent's port number
1100 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001101 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1102 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001103 e.Cancel(err)
1104 return
1105 }
1106 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001107 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001108 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001110}
1111
1112// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001113func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001114
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116 var err error
1117 /*
1118 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1119 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1120 return nil
1121 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1123 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001124 e.Cancel(err)
1125 return
1126 }
1127
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001128 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001130 // reconcilement will be continued after mib download is done
1131 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001132
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133 /*
1134 ############################################################################
1135 # Setup Alarm handler
1136 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1137 device.serial_number)
1138 ############################################################################
1139 # Setup PM configuration for this device
1140 # Pass in ONU specific options
1141 kwargs = {
1142 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1143 'heartbeat': self.heartbeat,
1144 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1145 }
1146 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1147 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1148 self.logical_device_id, device.serial_number,
1149 grouped=True, freq_override=False, **kwargs)
1150 pm_config = self._pm_metrics.make_proto()
1151 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1152 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1153 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1154
1155 # Note, ONU ID and UNI intf set in add_uni_port method
1156 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1157 ani_ports=[self._pon])
1158
1159 # Code to Run OMCI Test Action
1160 kwargs_omci_test_action = {
1161 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1162 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1163 }
1164 serial_number = device.serial_number
1165 self._test_request = OmciTestRequest(self.core_proxy,
1166 self.omci_agent, self.device_id,
1167 AniG, serial_number,
1168 self.logical_device_id,
1169 exclusive=False,
1170 **kwargs_omci_test_action)
1171
1172 self.enabled = True
1173 else:
1174 self.logger.info('onu-already-activated')
1175 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001176
dbainbri4d3a0dc2020-12-02 00:33:42 +00001177 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001178}
1179
1180// doStateConnected get the device info and update to voltha core
1181// for comparison of the original method (not that easy to uncomment): compare here:
1182// voltha-openolt-adapter/adaptercore/device_handler.go
1183// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001184func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001185
dbainbri4d3a0dc2020-12-02 00:33:42 +00001186 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301187 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001188 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001189 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001190}
1191
1192// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001194
dbainbri4d3a0dc2020-12-02 00:33:42 +00001195 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301196 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001197 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001199
1200 /*
1201 // Synchronous call to update device state - this method is run in its own go routine
1202 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1203 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001204 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 +00001205 return err
1206 }
1207 return nil
1208 */
1209}
1210
1211// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001212func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001213
dbainbri4d3a0dc2020-12-02 00:33:42 +00001214 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001215 var err error
1216
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001217 device := dh.device
1218 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001219 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001221 e.Cancel(err)
1222 return
1223 }
1224
1225 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001227 /*
1228 // Update the all ports state on that device to disable
1229 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001230 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001231 return er
1232 }
1233
1234 //Update the device oper state and connection status
1235 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1236 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1237 dh.device = cloned
1238
1239 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001240 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001241 return er
1242 }
1243
1244 //get the child device for the parent device
1245 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1246 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001247 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001248 return err
1249 }
1250 for _, onuDevice := range onuDevices.Items {
1251
1252 // Update onu state as down in onu adapter
1253 onuInd := oop.OnuIndication{}
1254 onuInd.OperState = "down"
1255 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1256 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1257 if er != nil {
1258 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001259 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001260 //Do not return here and continue to process other ONUs
1261 }
1262 }
1263 // * Discovered ONUs entries need to be cleared , since after OLT
1264 // is up, it starts sending discovery indications again* /
1265 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001266 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001267 return nil
1268 */
Himani Chawla4d908332020-08-31 12:30:20 +05301269 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001270 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001272}
1273
Himani Chawla6d2ae152020-09-02 13:11:20 +05301274// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001275// #################################################################################
1276
1277// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301278// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001279
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001280//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001282 dh.lockDevice.RLock()
1283 pOnuDeviceEntry := dh.pOnuOmciDevice
1284 if aWait && pOnuDeviceEntry == nil {
1285 //keep the read sema short to allow for subsequent write
1286 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001287 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001288 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1289 // so it might be needed to wait here for that event with some timeout
1290 select {
1291 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001293 return nil
1294 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001295 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001296 // if written now, we can return the written value without sema
1297 return dh.pOnuOmciDevice
1298 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001299 }
mpagenko3af1f032020-06-10 08:53:41 +00001300 dh.lockDevice.RUnlock()
1301 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001302}
1303
Himani Chawla6d2ae152020-09-02 13:11:20 +05301304//setOnuDeviceEntry sets the ONU device entry within the handler
1305func (dh *deviceHandler) setOnuDeviceEntry(
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301306 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001307 dh.lockDevice.Lock()
1308 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001309 dh.pOnuOmciDevice = apDeviceEntry
1310 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001311 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301312 dh.pAlarmMgr = apOnuAlarmMgr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001313}
1314
Himani Chawla6d2ae152020-09-02 13:11:20 +05301315//addOnuDeviceEntry creates a new ONU device or returns the existing
1316func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001317 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001318
dbainbri4d3a0dc2020-12-02 00:33:42 +00001319 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001320 if deviceEntry == nil {
1321 /* costum_me_map in python code seems always to be None,
1322 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1323 /* also no 'clock' argument - usage open ...*/
1324 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001325 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001326 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001327 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301328 onuAlarmManager := newAlarmManager(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001329 //error treatment possible //TODO!!!
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301330 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager)
mpagenko3af1f032020-06-10 08:53:41 +00001331 // fire deviceEntry ready event to spread to possibly waiting processing
1332 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001333 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001334 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001335 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001336 }
1337 // might be updated with some error handling !!!
1338 return nil
1339}
1340
dbainbri4d3a0dc2020-12-02 00:33:42 +00001341func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1342 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001343 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1344
1345 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001346
dbainbri4d3a0dc2020-12-02 00:33:42 +00001347 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001348 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001349 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001350 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1351 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001352 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001353 if err := dh.storePersistentData(ctx); err != nil {
1354 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001355 log.Fields{"device-id": dh.deviceID, "err": err})
1356 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001357 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001358 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001359 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001360 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1361 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001363 }
1364 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001365 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001366 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001367
1368 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001369 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 +00001370 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001371 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001372 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001373 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001374 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1375 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1376 // 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 +00001377 // 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 +00001378 // so let's just try to keep it simple ...
1379 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001380 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001381 if err != nil || device == nil {
1382 //TODO: needs to handle error scenarios
1383 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1384 return errors.New("Voltha Device not found")
1385 }
1386 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001387
dbainbri4d3a0dc2020-12-02 00:33:42 +00001388 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001389 return err
mpagenko3af1f032020-06-10 08:53:41 +00001390 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001391
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001392 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001393
1394 /* this might be a good time for Omci Verify message? */
1395 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001396 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001397 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001398 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001400
1401 /* give the handler some time here to wait for the OMCi verification result
1402 after Timeout start and try MibUpload FSM anyway
1403 (to prevent stopping on just not supported OMCI verification from ONU) */
1404 select {
1405 case <-time.After(2 * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001406 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001407 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001408 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001409 }
1410
1411 /* In py code it looks earlier (on activate ..)
1412 # Code to Run OMCI Test Action
1413 kwargs_omci_test_action = {
1414 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1415 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1416 }
1417 serial_number = device.serial_number
1418 self._test_request = OmciTestRequest(self.core_proxy,
1419 self.omci_agent, self.device_id,
1420 AniG, serial_number,
1421 self.logical_device_id,
1422 exclusive=False,
1423 **kwargs_omci_test_action)
1424 ...
1425 # Start test requests after a brief pause
1426 if not self._test_request_started:
1427 self._test_request_started = True
1428 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1429 reactor.callLater(tststart, self._test_request.start_collector)
1430
1431 */
1432 /* which is then: in omci_test_request.py : */
1433 /*
1434 def start_collector(self, callback=None):
1435 """
1436 Start the collection loop for an adapter if the frequency > 0
1437
1438 :param callback: (callable) Function to call to collect PM data
1439 """
1440 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1441 if callback is None:
1442 callback = self.perform_test_omci
1443
1444 if self.lc is None:
1445 self.lc = LoopingCall(callback)
1446
1447 if self.default_freq > 0:
1448 self.lc.start(interval=self.default_freq / 10)
1449
1450 def perform_test_omci(self):
1451 """
1452 Perform the initial test request
1453 """
1454 ani_g_entities = self._device.configuration.ani_g_entities
1455 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1456 is not None else None
1457 self._entity_id = ani_g_entities_ids[0]
1458 self.logger.info('perform-test', entity_class=self._entity_class,
1459 entity_id=self._entity_id)
1460 try:
1461 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1462 result = yield self._device.omci_cc.send(frame)
1463 if not result.fields['omci_message'].fields['success_code']:
1464 self.logger.info('Self-Test Submitted Successfully',
1465 code=result.fields[
1466 'omci_message'].fields['success_code'])
1467 else:
1468 raise TestFailure('Test Failure: {}'.format(
1469 result.fields['omci_message'].fields['success_code']))
1470 except TimeoutError as e:
1471 self.deferred.errback(failure.Failure(e))
1472
1473 except Exception as e:
1474 self.logger.exception('perform-test-Error', e=e,
1475 class_id=self._entity_class,
1476 entity_id=self._entity_id)
1477 self.deferred.errback(failure.Failure(e))
1478
1479 */
1480
1481 // PM related heartbeat??? !!!TODO....
1482 //self._heartbeat.enabled = True
1483
mpagenko1cc3cb42020-07-27 15:24:38 +00001484 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1485 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1486 * 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 +05301487 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001488 */
1489 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001490 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001491 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001492 if pMibUlFsm.Is(ulStDisabled) {
1493 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001494 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 +00001495 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301496 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301498 //Determine ONU status and start/re-start MIB Synchronization tasks
1499 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001500 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301501 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 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 +00001503 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001504 }
Himani Chawla4d908332020-08-31 12:30:20 +05301505 } else {
1506 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001507 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 +00001508 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301509 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001510 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001511 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001512 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001513 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001514 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001515 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001516 }
1517 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001519 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001520 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001521
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001522 if !dh.getCollectorIsRunning() {
1523 // Start PM collector routine
1524 go dh.startCollector(ctx)
1525 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301526 if !dh.getAlarmManagerIsRunning() {
1527 go dh.startAlarmManager(ctx)
1528 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301529
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530 return nil
1531}
1532
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001534 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001535 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001536 if dh.deviceReason != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001538
mpagenko900ee4b2020-10-12 11:56:34 +00001539 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1540 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1541 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001542 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001544 log.Fields{"device-id": dh.deviceID, "error": err})
1545 // abort: system behavior is just unstable ...
1546 return err
1547 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001548 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 _ = 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 +00001550
1551 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1552 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1553 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001555 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001557 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001558 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001559 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001560
1561 //TODO!!! remove existing traffic profiles
1562 /* from py code, if TP's exist, remove them - not yet implemented
1563 self._tp = dict()
1564 # Let TP download happen again
1565 for uni_id in self._tp_service_specific_task:
1566 self._tp_service_specific_task[uni_id].clear()
1567 for uni_id in self._tech_profile_download_done:
1568 self._tech_profile_download_done[uni_id].clear()
1569 */
1570
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001572
mpagenkofc4f56e2020-11-04 17:17:49 +00001573 dh.ReadyForSpecificOmciConfig = false
1574
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001576 // abort: system behavior is just unstable ...
1577 return err
1578 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001580 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001582 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001583 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001585 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001586 // abort: system behavior is just unstable ...
1587 return err
1588 }
1589 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001591 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001592 return nil
1593}
1594
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001595func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001596 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1597 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1598 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1599 // and using the stop/reset event should never harm
1600
dbainbri4d3a0dc2020-12-02 00:33:42 +00001601 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001602 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001604 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1605 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001606 if includingMibSyncFsm {
1607 //the MibSync FSM might be active all the ONU-active time,
1608 // hence it must be stopped unconditionally
1609 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1610 if pMibUlFsm != nil {
1611 _ = pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
1612 }
mpagenko900ee4b2020-10-12 11:56:34 +00001613 }
1614 //MibDownload may run
1615 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1616 if pMibDlFsm != nil {
1617 _ = pMibDlFsm.Event(dlEvReset)
1618 }
1619 //port lock/unlock FSM's may be active
1620 if dh.pUnlockStateFsm != nil {
1621 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1622 }
1623 if dh.pLockStateFsm != nil {
1624 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1625 }
1626 //techProfile related PonAniConfigFsm FSM may be active
1627 if dh.pOnuTP != nil {
1628 // should always be the case here
1629 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1630 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001631 for uniTP := range dh.pOnuTP.pAniConfigFsm {
1632 _ = dh.pOnuTP.pAniConfigFsm[uniTP].pAdaptFsm.pFsm.Event(aniEvReset)
1633 }
mpagenko900ee4b2020-10-12 11:56:34 +00001634 }
1635 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001636 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001637 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001638 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00001639 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001640 //VlanFilterFsm exists and was already started
1641 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
1642 if pVlanFilterStatemachine != nil {
mpagenkoa40e99a2020-11-17 13:50:39 +00001643 //reset of all Fsm is always accompanied by global persistency data removal
mpagenko2418ab02020-11-12 12:58:06 +00001644 // no need to remove specific data
1645 pVlanFilterFsm.RequestClearPersistency(false)
1646 //and reset the UniVlanConfig FSM
mpagenko900ee4b2020-10-12 11:56:34 +00001647 _ = pVlanFilterStatemachine.Event(vlanEvReset)
1648 }
mpagenkof1fc3862021-02-16 10:09:52 +00001649 } else {
1650 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001651 }
1652 }
1653 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001654 if dh.getCollectorIsRunning() {
1655 // Stop collector routine
1656 dh.stopCollector <- true
1657 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301658 if dh.getAlarmManagerIsRunning() {
1659 dh.stopAlarmManager <- true
1660 }
1661
mpagenko80622a52021-02-09 16:53:23 +00001662 //reset a possibly running upgrade FSM
1663 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1664 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1665 dh.lockUpgradeFsm.RLock()
1666 if dh.pOnuUpradeFsm != nil {
1667 _ = dh.pOnuUpradeFsm.pAdaptFsm.pFsm.Event(upgradeEvReset)
1668 }
1669 dh.lockUpgradeFsm.RUnlock()
1670
mpagenko900ee4b2020-10-12 11:56:34 +00001671 return nil
1672}
1673
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1675 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 +05301676
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001677 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001679 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001681 return
1682 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001683 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
mpagenko8b5fdd22020-12-17 17:58:32 +00001684 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1685 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
1686 for _, mgmtEntityID := range pptpInstKeys {
1687 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
1688 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301690 i++
1691 }
1692 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Debugw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301694 }
mpagenko8b5fdd22020-12-17 17:58:32 +00001695 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
1696 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Himani Chawla26e555c2020-08-31 12:30:20 +05301697 for _, mgmtEntityID := range veipInstKeys {
mpagenko8b5fdd22020-12-17 17:58:32 +00001698 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05301699 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
Himani Chawla26e555c2020-08-31 12:30:20 +05301701 i++
1702 }
1703 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301705 }
1706 if i == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 logger.Warnw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301708 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001709 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1710 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1711 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1712 * disable/enable toggling here to allow traffic
1713 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1714 * like the py comment says:
1715 * # start by locking all the unis till mib sync and initial mib is downloaded
1716 * # this way we can capture the port down/up events when we are ready
1717 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301718
mpagenkoa40e99a2020-11-17 13:50:39 +00001719 // Init Uni Ports to Admin locked state
1720 // *** should generate UniLockStateDone event *****
1721 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001723 } else { //LockStateFSM already init
1724 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001726 }
1727}
1728
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1730 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301731 /* Mib download procedure -
1732 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1733 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001735 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001737 return
1738 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301739 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1740 if pMibDlFsm != nil {
1741 if pMibDlFsm.Is(dlStDisabled) {
1742 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 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 +05301744 // maybe try a FSM reset and then again ... - TODO!!!
1745 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301747 // maybe use more specific states here for the specific download steps ...
1748 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301750 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301752 //Begin MIB data download (running autonomously)
1753 }
1754 }
1755 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001757 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301758 // maybe try a FSM reset and then again ... - TODO!!!
1759 }
1760 /***** Mib download started */
1761 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301763 }
1764}
1765
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1767 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301768 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001769 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001771 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001772 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1773 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1774 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1775 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301777 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1778 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301780 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301782 }
1783 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001785 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001787 return
1788 }
1789 if pDevEntry.sOnuPersistentData.PersUniDisableDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 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 +00001791 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001792 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001793 return
1794 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301796 log.Fields{"device-id": dh.deviceID})
1797 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001798 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001799
1800 // Initialize classical L2 PM Interval Counters
1801 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1802 // There is no way we should be landing here, but if we do then
1803 // there is nothing much we can do about this other than log error
1804 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1805 }
1806
mpagenkofc4f56e2020-11-04 17:17:49 +00001807 dh.ReadyForSpecificOmciConfig = true
Himani Chawla26e555c2020-08-31 12:30:20 +05301808 // *** should generate UniUnlockStateDone event *****
1809 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
Himani Chawla26e555c2020-08-31 12:30:20 +05301811 } else { //UnlockStateFSM already init
Himani Chawla6d2ae152020-09-02 13:11:20 +05301812 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 dh.runUniLockFsm(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +05301814 }
1815}
1816
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1818 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301819
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001820 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301822 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1824 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001825 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001827 return
1828 }
1829 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001830 if err := dh.storePersistentData(ctx); err != nil {
1831 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001832 log.Fields{"device-id": dh.deviceID, "err": err})
1833 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301834 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 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 +05301836 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001837 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001838 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301839 }
1840}
1841
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1843 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001844 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001846 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1847 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001849 }
1850
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001852 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001854
1855 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001857
dbainbri4d3a0dc2020-12-02 00:33:42 +00001858 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001859 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001861 return
1862 }
1863 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001864 if err := dh.storePersistentData(ctx); err != nil {
1865 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001866 log.Fields{"device-id": dh.deviceID, "err": err})
1867 }
mpagenko900ee4b2020-10-12 11:56:34 +00001868}
1869
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1871 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001872 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001874 voltha.OperStatus_ACTIVE); err != nil {
1875 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001877 }
1878
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001880 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001881 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001883
1884 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001886
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001888 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001890 return
1891 }
1892 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 if err := dh.storePersistentData(ctx); err != nil {
1894 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001895 log.Fields{"device-id": dh.deviceID, "err": err})
1896 }
mpagenko900ee4b2020-10-12 11:56:34 +00001897}
1898
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001900 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001901 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001902 // attention: the device reason update is done based on ONU-UNI-Port related activity
1903 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001904 if dh.deviceReason != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001905 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001906 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301907 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001908 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001909 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001910 }
1911 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001912 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001913 // attention: the device reason update is done based on ONU-UNI-Port related activity
1914 // - which may cause some inconsistency
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001915 if dh.deviceReason != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001916 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001917 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001918 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001919 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301920}
1921
dbainbri4d3a0dc2020-12-02 00:33:42 +00001922func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1923 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001924 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301925 // attention: the device reason update is done based on ONU-UNI-Port related activity
1926 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301927
mpagenkof1fc3862021-02-16 10:09:52 +00001928 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001929 if dh.deviceReason != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001930 // which may be the case from some previous actvity on another UNI Port of the ONU
1931 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001932 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1933 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 go dh.reconcileMetrics(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001935 }
1936 }
1937 } else {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00001938 if dh.deviceReason != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001939 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001941 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301942 }
mpagenkof1fc3862021-02-16 10:09:52 +00001943
1944 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
1945 //events that request KvStore write
1946 if err := dh.storePersistentData(ctx); err != nil {
1947 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
1948 log.Fields{"device-id": dh.deviceID, "err": err})
1949 }
1950 } else {
1951 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
1952 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001953 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301954}
1955
Himani Chawla6d2ae152020-09-02 13:11:20 +05301956//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05301958 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001959 case MibDatabaseSync:
1960 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001962 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001963 case UniLockStateDone:
1964 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00001966 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001967 case MibDownloadDone:
1968 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001970 }
1971 case UniUnlockStateDone:
1972 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001974 }
mpagenko900ee4b2020-10-12 11:56:34 +00001975 case UniEnableStateDone:
1976 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001978 }
1979 case UniDisableStateDone:
1980 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00001982 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001983 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00001984 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001985 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00001986 }
mpagenkof1fc3862021-02-16 10:09:52 +00001987 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00001988 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00001990 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001991 default:
1992 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001994 }
1995 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001996}
1997
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001999 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302001 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002002 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002004 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302005 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002006 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002007 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002009 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002010 //store UniPort with the System-PortNumber key
2011 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002012 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002013 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002014 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2015 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002016 } //error logging already within UniPort method
2017 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002018 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002019 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002020 }
2021 }
2022}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002023
mpagenko3af1f032020-06-10 08:53:41 +00002024// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002026 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302027 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002028 // with following remark:
2029 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2030 // # load on the core
2031
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002032 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002033
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002034 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002035 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302036 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002037 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302038 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002039 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002040 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002042 } else {
Andrea Campanellaab7b6a52020-10-06 16:17:13 +02002043 //TODO there is no retry mechanism, return error
dbainbri4d3a0dc2020-12-02 00:33:42 +00002044 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002045 }
mpagenko3af1f032020-06-10 08:53:41 +00002046 }
2047 }
2048}
2049
2050// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002052 // compare enableUniPortStateUpdate() above
2053 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2054 for uniNo, uniPort := range dh.uniEntityMap {
2055 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302056 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302058 uniPort.setOperState(vc.OperStatus_UNKNOWN)
mpagenko3af1f032020-06-10 08:53:41 +00002059 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002061 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002062 }
2063}
2064
2065// ONU_Active/Inactive announcement on system KAFKA bus
2066// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002067func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002068 var de voltha.DeviceEvent
2069 eventContext := make(map[string]string)
2070 //Populating event context
2071 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002073 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002074 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302075 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002076 }
2077 oltSerialNumber := parentDevice.SerialNumber
2078
2079 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2080 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2081 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302082 eventContext["olt-serial-number"] = oltSerialNumber
2083 eventContext["device-id"] = aDeviceID
2084 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002085 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002086 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002087
2088 /* Populating device event body */
2089 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302090 de.ResourceId = aDeviceID
2091 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002092 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2093 de.Description = fmt.Sprintf("%s Event - %s - %s",
2094 cEventObjectType, cOnuActivatedEvent, "Raised")
2095 } else {
2096 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2097 de.Description = fmt.Sprintf("%s Event - %s - %s",
2098 cEventObjectType, cOnuActivatedEvent, "Cleared")
2099 }
2100 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002101 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2102 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302103 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002104 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002105 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302106 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002107}
2108
Himani Chawla4d908332020-08-31 12:30:20 +05302109// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002110func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002111 chLSFsm := make(chan Message, 2048)
2112 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302113 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002115 sFsmName = "LockStateFSM"
2116 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002118 sFsmName = "UnLockStateFSM"
2119 }
mpagenko3af1f032020-06-10 08:53:41 +00002120
dbainbri4d3a0dc2020-12-02 00:33:42 +00002121 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002122 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002124 return
2125 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002127 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002128 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302129 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002130 dh.pLockStateFsm = pLSFsm
2131 } else {
2132 dh.pUnlockStateFsm = pLSFsm
2133 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002135 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002137 }
2138}
2139
2140// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002142 /* Uni Port lock/unlock procedure -
2143 ***** should run via 'adminDone' state and generate the argument requested event *****
2144 */
2145 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302146 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002147 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2148 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2149 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002150 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302151 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002152 }
2153 } else {
2154 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2155 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2156 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002157 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302158 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002159 }
2160 }
2161 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002162 if pLSStatemachine.Is(uniStDisabled) {
2163 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002165 // maybe try a FSM reset and then again ... - TODO!!!
2166 } else {
2167 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002168 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002169 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002170 }
2171 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002173 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002174 // maybe try a FSM reset and then again ... - TODO!!!
2175 }
2176 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002178 // maybe try a FSM reset and then again ... - TODO!!!
2179 }
2180}
2181
mpagenko80622a52021-02-09 16:53:23 +00002182// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002183func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002184 //in here lockUpgradeFsm is already locked
2185 chUpgradeFsm := make(chan Message, 2048)
2186 var sFsmName = "OnuSwUpgradeFSM"
2187 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002188 if apDevEntry.PDevOmciCC == nil {
2189 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2190 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002191 }
mpagenko15ff4a52021-03-02 10:09:20 +00002192 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002193 sFsmName, chUpgradeFsm)
2194 if dh.pOnuUpradeFsm != nil {
2195 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2196 if pUpgradeStatemachine != nil {
2197 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2198 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2199 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2200 // maybe try a FSM reset and then again ... - TODO!!!
2201 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2202 }
2203 /***** LockStateFSM started */
2204 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2205 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2206 } else {
2207 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2208 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2209 // maybe try a FSM reset and then again ... - TODO!!!
2210 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2211 }
2212 } else {
2213 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2214 // maybe try a FSM reset and then again ... - TODO!!!
2215 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2216 }
2217 } else {
2218 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2219 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2220 }
2221 return nil
2222}
2223
2224// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2225func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2226 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2227 "device-id": dh.deviceID})
2228 dh.lockUpgradeFsm.Lock()
2229 defer dh.lockUpgradeFsm.Unlock()
2230 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2231}
2232
mpagenko15ff4a52021-03-02 10:09:20 +00002233// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2234func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2235 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2236 if pDevEntry == nil {
2237 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2238 return
2239 }
2240
2241 dh.lockUpgradeFsm.RLock()
2242 defer dh.lockUpgradeFsm.RUnlock()
2243 if dh.pOnuUpradeFsm != nil {
2244 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2245 if pUpgradeStatemachine != nil {
2246 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2247 // (some manual forced commit could do without)
2248 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
2249 forcedTest := true //TODO!!: needed as long as BBSIM does not fully support SW upgrade simulation
2250 if forcedTest || pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
2251 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2252 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2253 return
2254 }
2255 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2256 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2257 } else {
2258 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2259 log.Fields{"device-id": dh.deviceID})
2260 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2261 return
2262 }
2263 }
2264 }
2265 } else {
2266 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2267 }
2268}
2269
Himani Chawla6d2ae152020-09-02 13:11:20 +05302270//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002271func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002272
2273 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002274 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002275 kvbackend := &db.Backend{
2276 Client: dh.pOpenOnuAc.kvClient,
2277 StoreType: dh.pOpenOnuAc.KVStoreType,
2278 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002279 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002280 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2281 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002282
mpagenkoaf801632020-07-03 10:00:42 +00002283 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002284}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302286 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002287
mpagenkodff5dda2020-08-28 11:52:01 +00002288 for _, field := range flow.GetOfbFields(apFlowItem) {
2289 switch field.Type {
2290 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2291 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002293 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2294 }
mpagenko01e726e2020-10-23 09:45:29 +00002295 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002296 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2297 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302298 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002299 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302300 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2301 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002302 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2303 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002304 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2305 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302306 return
mpagenkodff5dda2020-08-28 11:52:01 +00002307 }
2308 }
mpagenko01e726e2020-10-23 09:45:29 +00002309 */
mpagenkodff5dda2020-08-28 11:52:01 +00002310 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2311 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302312 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002313 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302314 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002315 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302316 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002317 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002318 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302319 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002320 }
2321 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2322 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302323 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002325 "PCP": loAddPcp})
2326 }
2327 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2328 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002329 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002330 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2331 }
2332 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2333 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002335 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2336 }
2337 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2338 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002339 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002340 "IPv4-DST": field.GetIpv4Dst()})
2341 }
2342 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2343 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002344 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002345 "IPv4-SRC": field.GetIpv4Src()})
2346 }
2347 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2348 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002349 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002350 "Metadata": field.GetTableMetadata()})
2351 }
2352 /*
2353 default:
2354 {
2355 //all other entires ignored
2356 }
2357 */
2358 }
2359 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302360}
mpagenkodff5dda2020-08-28 11:52:01 +00002361
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002363 for _, action := range flow.GetActions(apFlowItem) {
2364 switch action.Type {
2365 /* not used:
2366 case of.OfpActionType_OFPAT_OUTPUT:
2367 {
mpagenko01e726e2020-10-23 09:45:29 +00002368 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002369 "Output": action.GetOutput()})
2370 }
2371 */
2372 case of.OfpActionType_OFPAT_PUSH_VLAN:
2373 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002375 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2376 }
2377 case of.OfpActionType_OFPAT_SET_FIELD:
2378 {
2379 pActionSetField := action.GetSetField()
2380 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002381 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002382 "OxcmClass": pActionSetField.Field.OxmClass})
2383 }
2384 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302385 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302387 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002388 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302389 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002390 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302391 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002392 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002393 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002394 "Type": pActionSetField.Field.GetOfbField().Type})
2395 }
2396 }
2397 /*
2398 default:
2399 {
2400 //all other entires ignored
2401 }
2402 */
2403 }
2404 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302405}
2406
2407//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002408func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302409 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2410 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2411 var loAddPcp, loSetPcp uint8
2412 var loIPProto uint32
2413 /* the TechProfileId is part of the flow Metadata - compare also comment within
2414 * OLT-Adapter:openolt_flowmgr.go
2415 * Metadata 8 bytes:
2416 * Most Significant 2 Bytes = Inner VLAN
2417 * Next 2 Bytes = Tech Profile ID(TPID)
2418 * Least Significant 4 Bytes = Port ID
2419 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2420 * subscriber related flows.
2421 */
2422
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302424 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002425 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302426 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002427 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302428 }
mpagenko551a4d42020-12-08 18:09:20 +00002429 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002430 loCookie := apFlowItem.GetCookie()
2431 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002433 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302434
dbainbri4d3a0dc2020-12-02 00:33:42 +00002435 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002436 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302437 if loIPProto == 2 {
2438 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2439 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002440 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2441 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302442 return nil
2443 }
mpagenko01e726e2020-10-23 09:45:29 +00002444 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002446
2447 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002448 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002449 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2450 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2451 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2452 //TODO!!: Use DeviceId within the error response to rwCore
2453 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002454 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002455 }
2456 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002458 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2459 } else {
2460 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2461 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2462 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302463 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002464 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002466 }
mpagenko9a304ea2020-12-16 15:54:01 +00002467
2468 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002469 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002470 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302471 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002472 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002473 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002474 dh.lockVlanConfig.RUnlock()
2475 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002476 }
mpagenkof1fc3862021-02-16 10:09:52 +00002477 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002478 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002479 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002480}
2481
2482//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002484 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2485 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2486 //no extra check is done on the rule parameters
2487 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2488 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2489 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2490 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002491 // - some possible 'delete-all' sequence would have to be implemented separately (where the cookies are don't care anyway)
mpagenko01e726e2020-10-23 09:45:29 +00002492 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002494
2495 /* TT related temporary workaround - should not be needed anymore
2496 for _, field := range flow.GetOfbFields(apFlowItem) {
2497 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2498 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002499 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002500 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2501 if loIPProto == 2 {
2502 // some workaround for TT workflow on proto == 2 (IGMP trap) -> the flow was not added, no need to remove
mpagenko551a4d42020-12-08 18:09:20 +00002503 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002504 log.Fields{"device-id": dh.deviceID})
2505 return nil
2506 }
2507 }
2508 } //for all OfbFields
2509 */
2510
mpagenko9a304ea2020-12-16 15:54:01 +00002511 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002512 dh.lockVlanConfig.RLock()
2513 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002514 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002515 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002516 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002517 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002518 log.Fields{"device-id": dh.deviceID})
2519 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002520 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002521 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002522
mpagenko01e726e2020-10-23 09:45:29 +00002523 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002524}
2525
Himani Chawla26e555c2020-08-31 12:30:20 +05302526// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002527// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002528func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002529 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002530 chVlanFilterFsm := make(chan Message, 2048)
2531
dbainbri4d3a0dc2020-12-02 00:33:42 +00002532 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002533 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002534 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302535 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002536 }
2537
dbainbri4d3a0dc2020-12-02 00:33:42 +00002538 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002539 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2540 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002541 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002542 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302543 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002544 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002545 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2546 if pVlanFilterStatemachine != nil {
2547 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2548 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302550 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002551 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302552 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302554 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2555 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002556 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002558 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302559 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002560 }
2561 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002562 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002563 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302564 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002565 }
2566 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002567 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002568 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302569 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002570 }
2571 return nil
2572}
2573
mpagenkofc4f56e2020-11-04 17:17:49 +00002574//VerifyVlanConfigRequest checks on existence of a given uniPort
2575// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002576func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002577 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2578 var pCurrentUniPort *onuUniPort
2579 for _, uniPort := range dh.uniEntityMap {
2580 // only if this port is validated for operState transfer
2581 if uniPort.uniID == uint8(aUniID) {
2582 pCurrentUniPort = uniPort
2583 break //found - end search loop
2584 }
2585 }
2586 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002587 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002588 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2589 return
2590 }
mpagenko551a4d42020-12-08 18:09:20 +00002591 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002592}
2593
mpagenkodff5dda2020-08-28 11:52:01 +00002594//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002595func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002596 //TODO!! verify and start pending flow configuration
2597 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2598 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002599
2600 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302601 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002602 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002603 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2604 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2605 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002606 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2607 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2608 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2609 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2610 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2611 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2612 } else {
2613 /***** UniVlanConfigFsm continued */
2614 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2615 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2616 "UniPort": apUniPort.portNo})
2617 }
2618 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2619 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2620 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2621 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2622 } else {
2623 /***** UniVlanConfigFsm continued */
2624 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2625 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2626 "UniPort": apUniPort.portNo})
2627 }
mpagenkodff5dda2020-08-28 11:52:01 +00002628 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002629 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2630 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002631 "UniPort": apUniPort.portNo})
2632 }
2633 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002634 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2635 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2636 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002637 }
2638 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002639 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002640 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002641 }
mpagenkof1fc3862021-02-16 10:09:52 +00002642 } else {
2643 dh.lockVlanConfig.RUnlock()
2644 }
mpagenkodff5dda2020-08-28 11:52:01 +00002645}
2646
2647//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2648// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
dbainbri4d3a0dc2020-12-02 00:33:42 +00002649func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2650 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002651 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2652 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002653 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302654 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002655 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002656}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002657
Girish Gowdra26a40922021-01-29 17:14:34 -08002658//ProcessPendingTpDelete processes any pending TP delete (if available)
2659func (dh *deviceHandler) ProcessPendingTpDelete(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
2660 logger.Debugw(ctx, "enter processing pending tp delete", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2661 if apUniPort == nil {
2662 logger.Errorw(ctx, "uni port is nil", log.Fields{"device-id": dh.deviceID})
2663 return
2664 }
2665 k := uniTP{uniID: apUniPort.uniID, tpID: aTpID}
2666 if pAniConfigFsm, ok := dh.pOnuTP.pAniConfigFsm[k]; pAniConfigFsm != nil && ok {
2667 pAniConfigStatemachine := pAniConfigFsm.pAdaptFsm.pFsm
2668 if pAniConfigStatemachine != nil {
2669 //If the gem port delete was waiting on flow remove, indicate event that flow remove is done
2670 if pAniConfigStatemachine.Is(aniStWaitingFlowRem) {
2671 logger.Debugw(ctx, "ani fsm in aniStWaitingFlowRem state - handling aniEvFlowRemDone event",
2672 log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2673 if err := pAniConfigStatemachine.Event(aniEvFlowRemDone); err != nil {
2674 logger.Warnw(ctx, "AniConfigFsm: can't continue processing", log.Fields{"err": err,
2675 "device-id": dh.deviceID, "UniPort": apUniPort.portNo, "tpID": aTpID})
2676 return
2677 }
2678 } else {
2679 logger.Debugw(ctx, "ani fsm not in aniStWaitingFlowRem state", log.Fields{"device-id": dh.deviceID, "tpID": aTpID})
2680 return
2681 }
2682 }
2683 return
2684 }
2685}
2686
mpagenkof1fc3862021-02-16 10:09:52 +00002687//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2688func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2689 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2690 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2691 // obviously then parallel processing on the cancel must be avoided
2692 // deadline context to ensure completion of background routines waited for
2693 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2694 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2695 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2696
2697 aPDevEntry.resetKvProcessingErrorIndication()
2698 var wg sync.WaitGroup
2699 wg.Add(1) // for the 1 go routine to finish
2700
2701 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2702 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2703
2704 return aPDevEntry.getKvProcessingErrorIndication()
2705}
2706
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002707//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2708//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002709func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2710 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002711
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002712 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002713 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002714 return nil
2715 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002716 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002717
dbainbri4d3a0dc2020-12-02 00:33:42 +00002718 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002719 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002720 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002721 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2722 }
2723 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2724
mpagenkof1fc3862021-02-16 10:09:52 +00002725 if aWriteToKvStore {
2726 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2727 }
2728 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002729}
2730
dbainbri4d3a0dc2020-12-02 00:33:42 +00002731func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002732 defer cancel() //ensure termination of context (may be pro forma)
2733 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002734 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002735 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002736}
2737
dbainbri4d3a0dc2020-12-02 00:33:42 +00002738func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002739
2740 dh.deviceReason = deviceReason
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002741 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002742 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002743 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2744 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002745 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002746 return err
2747 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002748 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002749 return nil
2750 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002751 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002752 return nil
2753}
2754
dbainbri4d3a0dc2020-12-02 00:33:42 +00002755func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2756 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002757 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002758 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002759 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2760 }
mpagenkof1fc3862021-02-16 10:09:52 +00002761 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002762}
2763
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002764func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2765 var errStr string = ""
2766 for _, err := range errS {
2767 if err != nil {
2768 errStr = errStr + err.Error() + " "
2769 }
2770 }
2771 if errStr != "" {
2772 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2773 }
2774 return nil
2775}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002776
2777// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2778func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2779 dh.lockDevice.RLock()
2780 defer dh.lockDevice.RUnlock()
2781 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2782 return uniPort.entityID, nil
2783 }
2784 return 0, errors.New("error-fetching-uni-port")
2785}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002786
2787// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002788func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2789 var errorsList []error
2790 logger.Infow(ctx, "update-pm-config", log.Fields{"device-id": dh.device.Id, "new-pm-configs": pmConfigs, "old-pm-config": dh.pmConfigs})
Girish Gowdrae09a6202021-01-12 18:10:59 -08002791
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002792 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2793 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2794 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2795
2796 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2797 // successfully.
2798 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2799 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2800 if len(errorsList) > 0 {
2801 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2802 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002803 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002804 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2805 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002806}
2807
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002808func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2809 var err error
2810 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002811 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002812
2813 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2814 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2815 errorsList = append(errorsList, err)
2816 }
2817 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002818 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002819
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002820 return errorsList
2821}
2822
2823func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2824 var err error
2825 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002826 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002827 // Check if group metric related config is updated
2828 for _, v := range pmConfigs.Groups {
2829 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2830 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2831 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2832
2833 if ok && m.frequency != v.GroupFreq {
2834 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2835 errorsList = append(errorsList, err)
2836 }
2837 }
2838 if ok && m.enabled != v.Enabled {
2839 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2840 errorsList = append(errorsList, err)
2841 }
2842 }
2843 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002844 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002845 return errorsList
2846}
2847
2848func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2849 var err error
2850 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002851 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002852 // Check if standalone metric related config is updated
2853 for _, v := range pmConfigs.Metrics {
2854 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002855 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002856 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2857
2858 if ok && m.frequency != v.SampleFreq {
2859 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2860 errorsList = append(errorsList, err)
2861 }
2862 }
2863 if ok && m.enabled != v.Enabled {
2864 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2865 errorsList = append(errorsList, err)
2866 }
2867 }
2868 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002869 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002870 return errorsList
2871}
2872
2873// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002874func (dh *deviceHandler) startCollector(ctx context.Context) {
2875 logger.Debugf(ctx, "startingCollector")
2876
2877 // Start routine to process OMCI GET Responses
2878 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002879 // Initialize the next metric collection time.
2880 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2881 // reset like onu rebooted.
2882 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002883 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002884 for {
2885 select {
2886 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002887 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002888 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002889 // Stop the L2 PM FSM
2890 go func() {
2891 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2892 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2893 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2894 }
2895 } else {
2896 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2897 }
2898 }()
2899
Girish Gowdrae09a6202021-01-12 18:10:59 -08002900 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdrae0140f02021-02-02 16:55:09 -08002901 dh.pOnuMetricsMgr.stopTicks <- true
2902
Girish Gowdrae09a6202021-01-12 18:10:59 -08002903 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002904 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2905 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2906 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2907 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2908 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002909 // Update the next metric collection time.
2910 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002911 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002912 } else {
2913 if dh.pmConfigs.Grouped { // metrics are managed as a group
2914 // parse through the group and standalone metrics to see it is time to collect their metrics
2915 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002916
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002917 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2918 // If the group is enabled AND (current time is equal to OR after nextCollectionInterval, collect the group metric)
Girish Gowdrae0140f02021-02-02 16:55:09 -08002919 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2920 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002921 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2922 }
2923 }
2924 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2925 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2926 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2927 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2928 }
2929 }
2930 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2931
2932 // parse through the group and update the next metric collection time
2933 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
2934 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
2935 // If group enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
Girish Gowdrae0140f02021-02-02 16:55:09 -08002936 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
2937 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002938 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
2939 }
2940 }
2941 // parse through the standalone metrics and update the next metric collection time
2942 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2943 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
2944 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
2945 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
2946 }
2947 }
2948 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
2949 } /* else { // metrics are not managed as a group
2950 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
2951 } */
2952 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002953 }
2954 }
2955}
kesavandfdf77632021-01-26 23:40:33 -05002956
2957func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
2958
2959 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
2960 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
2961}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002962
mpagenkof1fc3862021-02-16 10:09:52 +00002963func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
2964 if pFsm == nil {
2965 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002966 }
mpagenkof1fc3862021-02-16 10:09:52 +00002967 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002968}
2969
mpagenkof1fc3862021-02-16 10:09:52 +00002970func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
2971 var pFsm *fsm.FSM
2972 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
2973 switch omciFsm {
2974 case cUploadFsm:
2975 {
2976 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
2977 }
2978 case cDownloadFsm:
2979 {
2980 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
2981 }
2982 case cUniLockFsm:
2983 {
2984 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
2985 }
2986 case cUniUnLockFsm:
2987 {
2988 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2989 }
2990 case cL2PmFsm:
2991 {
2992 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
2993 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
2994 } else {
2995 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002996 }
2997 }
mpagenko80622a52021-02-09 16:53:23 +00002998 case cOnuUpgradeFsm:
2999 {
3000 dh.lockUpgradeFsm.RLock()
3001 defer dh.lockUpgradeFsm.RUnlock()
3002 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3003 }
mpagenkof1fc3862021-02-16 10:09:52 +00003004 default:
3005 {
3006 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3007 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3008 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003009 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003010 }
mpagenkof1fc3862021-02-16 10:09:52 +00003011 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003012}
3013
mpagenkof1fc3862021-02-16 10:09:52 +00003014func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3015 for _, v := range dh.pOnuTP.pAniConfigFsm {
3016 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003017 return false
3018 }
3019 }
3020 return true
3021}
3022
mpagenkof1fc3862021-02-16 10:09:52 +00003023func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3024 dh.lockVlanConfig.RLock()
3025 defer dh.lockVlanConfig.RUnlock()
3026 for _, v := range dh.UniVlanConfigFsmMap {
3027 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3028 return false
3029 }
3030 }
3031 return true //FSM not active - so there is no activity on omci
3032}
3033
3034func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3035 dh.lockVlanConfig.RLock()
3036 defer dh.lockVlanConfig.RUnlock()
3037 for _, v := range dh.UniVlanConfigFsmMap {
3038 if v.pAdaptFsm.pFsm != nil {
3039 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3040 return true //there is at least one VLAN FSM with some active configuration
3041 }
3042 }
3043 }
3044 return false //there is no VLAN FSM with some active configuration
3045}
3046
3047func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3048 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3049 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3050 return false
3051 }
3052 }
3053 // a further check is done to identify, if at least some data traffic related configuration exists
3054 // so that a user of this ONU could be 'online' (otherwise it makes no sense to check the MDS [with the intention to keep the user service up])
3055 return dh.checkUserServiceExists(ctx)
3056}
3057
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003058func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3059 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3060 if err := dh.resetFsms(ctx, false); err != nil {
3061 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3062 // TODO: fatal error reset ONU, delete deviceHandler!
3063 return
3064 }
3065 if !dh.getCollectorIsRunning() {
3066 // Start PM collector routine
3067 go dh.startCollector(ctx)
3068 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303069 if !dh.getAlarmManagerIsRunning() {
3070 go dh.startAlarmManager(ctx)
3071 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003072 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003073 dh.startReconciling(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003074}
3075
3076func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3077 dh.mutexCollectorFlag.Lock()
3078 dh.collectorIsRunning = flagValue
3079 dh.mutexCollectorFlag.Unlock()
3080}
3081
3082func (dh *deviceHandler) getCollectorIsRunning() bool {
3083 dh.mutexCollectorFlag.RLock()
3084 flagValue := dh.collectorIsRunning
3085 dh.mutexCollectorFlag.RUnlock()
3086 return flagValue
3087}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303088
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303089func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3090 dh.mutextAlarmManagerFlag.Lock()
3091 dh.alarmManagerIsRunning = flagValue
3092 dh.mutextAlarmManagerFlag.Unlock()
3093}
3094
3095func (dh *deviceHandler) getAlarmManagerIsRunning() bool {
3096 dh.mutextAlarmManagerFlag.RLock()
3097 flagValue := dh.alarmManagerIsRunning
3098 dh.mutextAlarmManagerFlag.RUnlock()
3099 return flagValue
3100}
3101
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303102func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3103 logger.Debugf(ctx, "startingAlarmManager")
3104
3105 // Start routine to process OMCI GET Responses
3106 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303107 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303108 if stop := <-dh.stopAlarmManager; stop {
3109 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
3110 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303111 dh.setAlarmManagerIsRunning(false)
3112
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303113 }
3114}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003115
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003116func (dh *deviceHandler) startReconciling(ctx context.Context) {
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003117 logger.Debugw(ctx, "start reconciling", log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003118 if !dh.isReconciling() {
3119 go func() {
3120 select {
3121 case <-dh.chReconcilingFinished:
3122 logger.Debugw(ctx, "reconciling has been finished in time",
3123 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003124 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003125 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3126 log.Fields{"device-id": dh.deviceID})
3127 }
3128 dh.mutexReconcilingFlag.Lock()
3129 dh.reconciling = false
3130 dh.mutexReconcilingFlag.Unlock()
3131 }()
3132 dh.mutexReconcilingFlag.Lock()
3133 dh.reconciling = true
3134 dh.mutexReconcilingFlag.Unlock()
3135 } else {
3136 logger.Warnw(ctx, "reconciling is already running", log.Fields{"device-id": dh.deviceID})
3137 }
3138}
3139
3140func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3141 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3142 if dh.isReconciling() {
3143 dh.chReconcilingFinished <- true
3144 } else {
3145 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3146 }
3147}
3148
3149func (dh *deviceHandler) isReconciling() bool {
3150 dh.mutexReconcilingFlag.RLock()
3151 value := dh.reconciling
3152 dh.mutexReconcilingFlag.RUnlock()
3153 return value
3154}