blob: c14008edba75822ec37ebec1b92f2e4890ae91be [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2020-2023 Open Networking Foundation (ONF) and the ONF Contributors
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003 *
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
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package core provides the utility for onu devices, flows and statistics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
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
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
kesavand011d5162021-11-25 19:21:06 +053047 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo7d3c5582021-08-11 18:09:44 -040048 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040049 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040050 "github.com/opencord/voltha-protos/v5/go/extension"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000051 "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo42dcdfd2021-10-19 17:34:12 -040052 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000054 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040055 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000056 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040057 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt2b107642022-12-09 07:56:23 +000058 "google.golang.org/grpc/codes"
59 "google.golang.org/grpc/status"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060)
61
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000062const (
mpagenko101ac942021-11-16 15:01:29 +000063 //constants for reconcile flow check channel
64 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
65 cWaitReconcileFlowAbortOnError = 0xFFFE
66 cWaitReconcileFlowNoActivity = 0xFFFF
67)
68
69const (
70 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000071 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000072)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000073
mpagenko1cc3cb42020-07-27 15:24:38 +000074const (
mpagenko44bd8362021-11-15 11:40:05 +000075 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
76 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
77 // as long as such is not available by the libraries - use this workaround
78 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
79)
80
81const (
mpagenko1cc3cb42020-07-27 15:24:38 +000082 // events of Device FSM
83 devEvDeviceInit = "devEvDeviceInit"
84 devEvGrpcConnected = "devEvGrpcConnected"
85 devEvGrpcDisconnected = "devEvGrpcDisconnected"
86 devEvDeviceUpInd = "devEvDeviceUpInd"
87 devEvDeviceDownInd = "devEvDeviceDownInd"
88)
89const (
90 // states of Device FSM
91 devStNull = "devStNull"
92 devStDown = "devStDown"
93 devStInit = "devStInit"
94 devStConnected = "devStConnected"
95 devStUp = "devStUp"
96)
97
praneeth nalmas5a0a5502022-12-23 15:57:00 +053098// Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
Holger Hildebrandt24d51952020-05-04 14:03:42 +000099const (
Himani Chawla4d908332020-08-31 12:30:20 +0530100 pon = voltha.EventSubCategory_PON
101 //olt = voltha.EventSubCategory_OLT
102 //ont = voltha.EventSubCategory_ONT
103 //onu = voltha.EventSubCategory_ONU
104 //nni = voltha.EventSubCategory_NNI
105 //service = voltha.EventCategory_SERVICE
106 //security = voltha.EventCategory_SECURITY
107 equipment = voltha.EventCategory_EQUIPMENT
108 //processing = voltha.EventCategory_PROCESSING
109 //environment = voltha.EventCategory_ENVIRONMENT
110 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000111)
112
113const (
114 cEventObjectType = "ONU"
115)
116const (
117 cOnuActivatedEvent = "ONU_ACTIVATED"
118)
119
mpagenkof1fc3862021-02-16 10:09:52 +0000120type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000122 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
126 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
127 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
128 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
129 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
130 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
131 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
132 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
133 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000134}
135
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000136const (
137 cNoReconciling = iota
138 cOnuConfigReconciling
139 cSkipOnuConfigReconciling
140)
141
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142// FlowCb is the flow control block containing flow add/delete information along with a response channel
143type FlowCb struct {
144 ctx context.Context // Flow handler context
145 addFlow bool // if true flow to be added, else removed
146 flowItem *of.OfpFlowStats
147 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400148 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700149 respChan *chan error // channel to report the Flow handling error
150}
151
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530152// deviceHandler will interact with the ONU ? device.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530153type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000154 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155 DeviceType string
156 adminState string
157 device *voltha.Device
158 logicalDeviceID string
159 ProxyAddressID string
160 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530161 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000162 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163
khenaidoo7d3c5582021-08-11 18:09:44 -0400164 coreClient *vgrpc.Client
165 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000166
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800167 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400168 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800169
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170 pOpenOnuAc *OpenONUAC
171 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530172 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000173 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000174 pOnuOmciDevice *mib.OnuDeviceEntry
175 pOnuTP *avcfg.OnuUniTechProf
176 pOnuMetricsMgr *pmmgr.OnuMetricsManager
177 pAlarmMgr *almgr.OnuAlarmManager
178 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000179 exitChannel chan int
180 lockDevice sync.RWMutex
181 pOnuIndication *oop.OnuIndication
182 deviceReason uint8
183 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000184 pLockStateFsm *uniprt.LockStateFsm
185 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000186
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187 //flowMgr *OpenOltFlowMgr
188 //eventMgr *OpenOltEventMgr
189 //resourceMgr *rsrcMgr.OpenOltResourceMgr
190
191 //discOnus sync.Map
192 //onus sync.Map
193 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000194 collectorIsRunning bool
195 mutexCollectorFlag sync.RWMutex
196 stopCollector chan bool
197 alarmManagerIsRunning bool
198 mutextAlarmManagerFlag sync.RWMutex
199 stopAlarmManager chan bool
200 stopHeartbeatCheck chan bool
201 uniEntityMap cmn.OnuUniPortMap
202 mutexKvStoreContext sync.Mutex
203 lockVlanConfig sync.RWMutex
204 lockVlanAdd sync.RWMutex
205 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
206 lockUpgradeFsm sync.RWMutex
207 pOnuUpradeFsm *swupg.OnuUpgradeFsm
208 upgradeCanceled bool
209 reconciling uint8
210 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000211 reconcilingFirstPass bool
212 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000213 reconcilingReasonUpdate bool
214 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000215 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
216 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
217 reconcileExpiryComplete time.Duration
218 reconcileExpiryVlanConfig time.Duration
219 mutexReadyForOmciConfig sync.RWMutex
220 readyForOmciConfig bool
221 deletionInProgress bool
222 mutexDeletionInProgressFlag sync.RWMutex
223 pLastUpgradeImageState *voltha.ImageState
224 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700225
226 flowCbChan []chan FlowCb
227 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300228 mutexForDisableDeviceRequested sync.RWMutex
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000229 mutexOltAvailable sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700230 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
231 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300232 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000233 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000234}
235
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530236// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400237func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530238 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400239 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400241 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000243 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 dh.DeviceType = cloned.Type
245 dh.adminState = "up"
246 dh.device = cloned
247 dh.pOpenOnuAc = adapter
248 dh.exitChannel = make(chan int, 1)
249 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000250 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000251 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530253 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530254 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopHeartbeatCheck = make(chan bool, 2)
256 //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 +0000257 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000258 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000259 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000260 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000261 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300262 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000263 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000264 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000265 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000266 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300267 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000268 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000269 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000270 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
271 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
272 if rECSeconds < 2 {
273 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
274 rECSeconds = 2
275 }
276 rEVCSeconds := rECSeconds / 2
277 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000278 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000279 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000280 dh.pLastUpgradeImageState = &voltha.ImageState{
281 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
282 Reason: voltha.ImageState_UNKNOWN_ERROR,
283 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
284 }
285 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800287 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
288 dh.pmConfigs = cloned.PmConfigs
289 } /* else {
290 // will be populated when onu_metrics_mananger is initialized.
291 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800292
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 // Device related state machine
294 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000295 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000297 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
298 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
299 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
300 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
301 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 },
303 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000304 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
305 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
306 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
307 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
308 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
309 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
310 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
311 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312 },
313 )
mpagenkoaf801632020-07-03 10:00:42 +0000314
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 return &dh
316}
317
Himani Chawla6d2ae152020-09-02 13:11:20 +0530318// start save the device to the data model
319func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000320 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000322 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323}
324
Himani Chawla4d908332020-08-31 12:30:20 +0530325/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 logger.Debug("stopping-device-handler")
329 dh.exitChannel <- 1
330}
Himani Chawla4d908332020-08-31 12:30:20 +0530331*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332
333// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530334// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000335
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530336// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530337func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400338 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000340 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530341
mpagenko1cc3cb42020-07-27 15:24:38 +0000342 if dh.pDeviceStateFsm.Is(devStNull) {
343 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000344 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"device-id": device.Id, "err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000346 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800347 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
348 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800349 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400350 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000351 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800352 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800353 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000354 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000356 }
357
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000358}
359
khenaidoo42dcdfd2021-10-19 17:34:12 -0400360func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000361 /* 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 +0530362 //assuming omci message content is hex coded!
363 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000365 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000366 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000367 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530368 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000369 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000370 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000371 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000372 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
373 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
376 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530377}
378
khenaidoo42dcdfd2021-10-19 17:34:12 -0400379func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000380 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000381
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000383 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
385 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000386 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530387 if dh.pOnuTP == nil {
388 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000390 log.Fields{"device-id": dh.DeviceID})
391 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000393 if !dh.IsReadyForOmciConfig() {
394 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
395 "device-state": dh.GetDeviceReasonString()})
396 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530397 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000398 //previous state test here was just this one, now extended for more states to reject the SetRequest:
399 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
400 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530401
Himani Chawla26e555c2020-08-31 12:30:20 +0530402 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
404 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000405 dh.pOnuTP.LockTpProcMutex()
406 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000407
mpagenko44bd8362021-11-15 11:40:05 +0000408 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000410 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411 }
412 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000413 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800414 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000415 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
416 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800417 return err
418 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000419 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
420 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000421
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000422 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530423
Girish Gowdra50e56422021-06-01 16:46:04 -0700424 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400425 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000426 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
427 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000428
429 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
430 if err != nil {
431 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
432 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
433 // stopping all further processing
434 _ = dh.UpdateInterface(ctx)
435 return err
436 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700437 // if there has been some change for some uni TechProfilePath
438 //in order to allow concurrent calls to other dh instances we do not wait for execution here
439 //but doing so we can not indicate problems to the caller (who does what with that then?)
440 //by now we just assume straightforward successful execution
441 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
442 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530443
Girish Gowdra50e56422021-06-01 16:46:04 -0700444 // deadline context to ensure completion of background routines waited for
445 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
446 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
447 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700450
451 var wg sync.WaitGroup
452 wg.Add(1) // for the 1 go routine to finish
453 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000454 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700455 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
457 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700458 return tpErr
459 }
460 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
461 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000462 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700463 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000464 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700465 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000466 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
467 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.DeviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700468 return kvErr
469 }
470 return nil
471 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000472 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700473 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700474 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000477 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
478 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530479 return nil
480}
481
khenaidoo42dcdfd2021-10-19 17:34:12 -0400482func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000483 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530484
485 if dh.pOnuTP == nil {
486 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000488 log.Fields{"device-id": dh.DeviceID})
489 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 dh.pOnuTP.LockTpProcMutex()
493 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530494
mpagenko0f543222021-11-03 16:24:14 +0000495 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
496 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
497 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000499 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 }
501 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800503 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000504 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
505 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800506 return err
507 }
mpagenko0f543222021-11-03 16:24:14 +0000508 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
509 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000510 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511
Mahir Gunyel9545be22021-07-04 15:53:16 -0700512 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514
Himani Chawla26e555c2020-08-31 12:30:20 +0530515}
516
khenaidoo42dcdfd2021-10-19 17:34:12 -0400517func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000518 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000520 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000521 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000522 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
523 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530525 if dh.pOnuTP == nil {
526 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000528 log.Fields{"device-id": dh.DeviceID})
529 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530530 }
531
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 dh.pOnuTP.LockTpProcMutex()
534 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000535
mpagenko0f543222021-11-03 16:24:14 +0000536 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
537 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
538 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 }
542 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700543 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000544 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800545 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000546 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
547 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800548 return err
549 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530551
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000552 var wg sync.WaitGroup
553 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
554 dctx, cancel := context.WithDeadline(context.Background(), deadline)
555 wg.Add(1)
556 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
557 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
558 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
559 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
560 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
561 return err
562 }
563
Mahir Gunyel9545be22021-07-04 15:53:16 -0700564 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000566
Mahir Gunyel9545be22021-07-04 15:53:16 -0700567}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000568
Mahir Gunyel9545be22021-07-04 15:53:16 -0700569func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000570 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
571 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700572 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
574 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530575 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700576 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000577 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700578 resourceName = "Gem"
579 } else {
580 resourceName = "Tcont"
581 }
582
583 // deadline context to ensure completion of background routines waited for
584 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
585 dctx, cancel := context.WithDeadline(context.Background(), deadline)
586
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000587 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700588
589 var wg sync.WaitGroup
590 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700592 resource, entryID, &wg)
593 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000594 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
595 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700596 return err
597 }
598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
600 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
601 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
602 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700603 var wg2 sync.WaitGroup
604 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
605 wg2.Add(1)
606 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000607 logger.Debugw(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000608 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700609 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
611 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700612 return err
613 }
614 }
615 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700617 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530618 return nil
619}
620
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530621// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400623 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400624 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700625 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
626 var errorsList []error
627 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000628 //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 +0000629 if apOfFlowChanges.ToRemove != nil {
630 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000631 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000633 "device-id": dh.DeviceID})
634 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700635 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000636 continue
637 }
638 flowInPort := flow.GetInPort(flowItem)
639 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
641 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700642 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000643 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000645 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000646 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000649 continue
650 } else {
651 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000653 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
654 loUniPort = uniPort
655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000657 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000658 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700660 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000661 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000662 }
663 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000664 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000665 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
666 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700667
668 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
669 // Step1 : Fill flowControlBlock
670 // Step2 : Push the flowControlBlock to ONU channel
671 // Step3 : Wait on response channel for response
672 // Step4 : Return error value
673 startTime := time.Now()
674 respChan := make(chan error)
675 flowCb := FlowCb{
676 ctx: ctx,
677 addFlow: false,
678 flowItem: flowItem,
679 flowMetaData: nil,
680 uniPort: loUniPort,
681 respChan: &respChan,
682 }
683 dh.flowCbChan[loUniPort.UniID] <- flowCb
684 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
685 // Wait on the channel for flow handlers return value
686 retError = <-respChan
687 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
688 if retError != nil {
689 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
690 log.Fields{"device-id": dh.DeviceID, "error": retError})
691 errorsList = append(errorsList, retError)
692 continue
693 }
694 } else {
695 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
696 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000697 }
698 }
699 }
700 }
mpagenko01e726e2020-10-23 09:45:29 +0000701 if apOfFlowChanges.ToAdd != nil {
702 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
703 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000705 "device-id": dh.DeviceID})
706 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700707 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000708 continue
709 }
710 flowInPort := flow.GetInPort(flowItem)
711 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000712 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
713 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700714 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000715 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000716 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000717 } else if flowInPort == dh.ponPortNumber {
718 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000720 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000721 continue
722 } else {
723 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000724 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000725 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
726 loUniPort = uniPort
727 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000730 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000731 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700732 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000733 continue
mpagenko01e726e2020-10-23 09:45:29 +0000734 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000735 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
736 // if not, we just throw some error here to have an indication about that, if we really need to support that
737 // then we would need to create some means to activate the internal stored flows
738 // after the device gets active automatically (and still with its dependency to the TechProfile)
739 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
740 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000741 if !dh.IsReadyForOmciConfig() {
742 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
743 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700744 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
745 errorsList = append(errorsList, retError)
746 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000747 }
748
mpagenko01e726e2020-10-23 09:45:29 +0000749 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000751 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
752 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700753 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
754 // Step1 : Fill flowControlBlock
755 // Step2 : Push the flowControlBlock to ONU channel
756 // Step3 : Wait on response channel for response
757 // Step4 : Return error value
758 startTime := time.Now()
759 respChan := make(chan error)
760 flowCb := FlowCb{
761 ctx: ctx,
762 addFlow: true,
763 flowItem: flowItem,
764 flowMetaData: apFlowMetaData,
765 uniPort: loUniPort,
766 respChan: &respChan,
767 }
768 dh.flowCbChan[loUniPort.UniID] <- flowCb
769 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
770 // Wait on the channel for flow handlers return value
771 retError = <-respChan
772 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
773 if retError != nil {
774 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
775 log.Fields{"device-id": dh.DeviceID, "error": retError})
776 errorsList = append(errorsList, retError)
777 continue
778 }
779 } else {
780 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
781 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000782 }
783 }
784 }
785 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700786 if len(errorsList) > 0 {
787 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
788 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
789 }
790 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000791}
792
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530793// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
794// following are the expected device states after this activity:
795// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000796// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
798 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300799 dh.mutexForDisableDeviceRequested.Lock()
800 dh.disableDeviceRequested = true
801 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000802 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000803 //note that disableDevice sequences in some 'ONU active' state may yield also
804 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000805 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000807 //disable-device shall be just a UNi/ONU-G related admin state setting
808 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000809
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000810 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000811 // disable UNI ports/ONU
812 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
813 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000815 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000816 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000818 }
819 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000820 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000822 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400823 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000825 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400826 OperStatus: voltha.OperStatus_UNKNOWN,
827 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000828 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000830 }
mpagenko01e726e2020-10-23 09:45:29 +0000831 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000832
833 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000834 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000835 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300836 }
837}
838
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530839// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
841 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000842
mpagenkoaa3afe92021-05-21 16:20:58 +0000843 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000844 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
845 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
846 // for real ONU's that should have nearly no influence
847 // Note that for real ONU's there is anyway a problematic situation with following sequence:
848 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
849 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
850 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000852
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000853 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000854 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300855 dh.mutexForDisableDeviceRequested.Lock()
856 dh.disableDeviceRequested = false
857 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000858 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000860 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000863 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300864}
865
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530867 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000868
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000869 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 return
873 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000874 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000875 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000877 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000879 }
mpagenko101ac942021-11-16 15:01:29 +0000880 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000881 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000882 }
Himani Chawla4d908332020-08-31 12:30:20 +0530883 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 pDevEntry.MutexPersOnuConfig.RLock()
885 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
886 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
887 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
888 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
889 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000890 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000891}
892
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000893func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530894 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000895
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000896 continueWithFlowConfig := false
897
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000898 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000900 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000901 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
902 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000904 dh.pOnuTP.LockTpProcMutex()
905 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000906
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000907 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000908 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
910 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530911 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000913 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
914 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000915 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000916 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700917 techProfsFound := false
918 techProfInstLoadFailed := false
919outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000920 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000921 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000922 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000923 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000924 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000925 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000926 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000927 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000928 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
929 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000930 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000931 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000932 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700933 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000934 var iaTechTpInst ia.TechProfileDownloadMessage
935 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800936 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000937 pDevEntry.MutexReconciledTpInstances.RLock()
938 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
939 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000940 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000941 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700942 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000943 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700944 break outerLoop
945 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000946 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000947 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700948 var tpInst tech_profile.TechProfileInstance
949 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400950 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700951 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000952 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700954 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000955 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700957 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
958 break outerLoop
959 }
960
Girish Gowdra041dcb32020-11-16 16:54:30 -0800961 // deadline context to ensure completion of background routines waited for
962 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
963 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000965
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000966 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800967 var wg sync.WaitGroup
968 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000969 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000970 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
972 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700973 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
974 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800975 }
mpagenko2dc896e2021-08-02 12:03:59 +0000976 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000977 if len(uniData.PersFlowParams) != 0 {
978 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000979 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000981 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 } // for all UNI entries from SOnuPersistentData
983 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
984 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000985 }
mpagenko2dc896e2021-08-02 12:03:59 +0000986
987 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
988 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000989
990 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000991}
992
993func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
994 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
995 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530996 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000997 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000998 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000999 return
1000 }
mpagenko2dc896e2021-08-02 12:03:59 +00001001 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001002 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001003 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001004 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001005 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001006 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001007 }
mpagenko2dc896e2021-08-02 12:03:59 +00001008 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301009 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001011 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001012 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013}
1014
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1016 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001018 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001020 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001021 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001022 return
1023 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001024
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001025 pDevEntry.MutexPersOnuConfig.RLock()
1026 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1027 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301028 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001030 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001031 return
1032 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001033 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001034 var uniVlanConfigEntries []uint8
1035 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1036
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001037 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001038 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1039 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001040 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 continue
1043 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001044 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001045 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001046 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001047 // It doesn't make sense to configure any flows if no TPs are available
1048 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001049 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001050 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1051 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001052 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001054
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001056 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001057 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1060 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001061 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001062 return
1063 }
mpagenko101ac942021-11-16 15:01:29 +00001064 //needed to split up function due to sca complexity
1065 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1066
mpagenko2dc896e2021-08-02 12:03:59 +00001067 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001068 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001069 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1070 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001071 // this can't be used as global finished reconciling flag because
1072 // assumes is getting called before the state machines for the last flow is completed,
1073 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1075 } // for all UNI entries from SOnuPersistentData
1076 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001077
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001078 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301079 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001080 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001081 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001082 return
1083 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001084 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1085 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1086 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1087 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1088 log.Fields{"device-id": dh.DeviceID})
1089 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1090 if pDevEntry != nil {
1091 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001092 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001093 } else {
1094 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1095 log.Fields{"device-id": dh.DeviceID})
1096 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1097 if pDevEntry != nil {
1098 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1099 }
1100 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001101 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001102 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001103}
1104
mpagenko101ac942021-11-16 15:01:29 +00001105func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1106 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1107 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1108 flowsProcessed := 0
1109 lastFlowToReconcile := false
1110 loUniID := apUniPort.UniID
1111 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001112 if !(*apFlowsFound) {
1113 *apFlowsFound = true
1114 syncChannel := make(chan struct{})
1115 // start go routine with select() on reconciling vlan config channel before
1116 // starting vlan config reconciling process to prevent loss of any signal
1117 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1118 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1119 //block until the wait routine is really blocked on channel input
1120 // in order to prevent to early ready signal from VlanConfig processing
1121 <-syncChannel
1122 }
1123 if flowsProcessed == len(aPersFlowParam)-1 {
1124 var uniAdded bool
1125 lastFlowToReconcile = true
1126 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1127 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001128 }
1129 }
mpagenko101ac942021-11-16 15:01:29 +00001130 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1131 "device-id": dh.DeviceID, "uni-id": loUniID,
1132 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1133 dh.lockVlanConfig.Lock()
1134 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1135 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1136 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301137 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid), uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001138 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1139 }
1140 } else {
1141 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301142 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301143 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001144 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1145 }
1146 }
1147 dh.lockVlanConfig.Unlock()
1148 flowsProcessed++
1149 } //for all flows of this UNI
1150}
1151
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301152// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1153//
1154// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001155func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1156 waitGroup *cmn.WaitGroupWithTimeOut) {
1157 var reconciledUniVlanConfigEntries []uint8
1158 var appended bool
1159 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1160 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1161 "device-id": dh.DeviceID, "expiry": expiry})
1162 // indicate blocking on channel now to the caller
1163 aSyncChannel <- struct{}{}
1164 for {
1165 select {
1166 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1167 switch uniIndication {
1168 // no activity requested (should normally not be received) - just continue waiting
1169 case cWaitReconcileFlowNoActivity:
1170 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1171 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301172 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001173 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1174 return
1175 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1176 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301177 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001178 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1179 return
1180 // this should be a valid UNI vlan config done indication
1181 default:
1182 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301183 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001184 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1185 if reconciledUniVlanConfigEntries, appended =
1186 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1187 waitGroup.Done()
1188 }
1189 } else {
1190 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1191 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1192 }
1193 } //switch uniIndication
1194
1195 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1196 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1197 log.Fields{"device-id": dh.DeviceID})
1198 return
1199 }
1200 }
1201}
1202
1203func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1204 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1205}
1206
1207func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1208 for _, ele := range slice {
1209 if ele == val {
1210 return slice, false
1211 }
1212 }
1213 return append(slice, val), true
1214}
1215
1216// sendChReconcileFinished - sends true or false on reconcileFinish channel
1217func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1218 if dh != nil { //if the object still exists (might have been already deleted in background)
1219 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1220 select {
1221 case dh.chReconcilingFinished <- success:
1222 default:
1223 }
1224 }
1225}
1226
1227// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1228func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1229 if dh != nil { //if the object still exists (might have been already deleted in background)
1230 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1231 select {
1232 case dh.chUniVlanConfigReconcilingDone <- value:
1233 default:
1234 }
1235 }
1236}
1237
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001240
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001242 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001243 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001245 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001246 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001247
1248 // deadline context to ensure completion of background routines waited for
1249 //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 +05301250 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001252
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001253 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001254
1255 var wg sync.WaitGroup
1256 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001257 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001258 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001259
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001260 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001261 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001262}
1263
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301264// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001265// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301266//
1267// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1268//
1269// was and is called in background - error return does not make sense
mpagenko15ff4a52021-03-02 10:09:20 +00001270func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001271 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001272 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001274 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001275 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001276 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301277 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001278 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001279 return
Himani Chawla4d908332020-08-31 12:30:20 +05301280 }
mpagenko01e726e2020-10-23 09:45:29 +00001281
1282 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001284
mpagenko44bd8362021-11-15 11:40:05 +00001285 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001287 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
khenaidoo42dcdfd2021-10-19 17:34:12 -04001288 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001289 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001290 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001291 OperStatus: voltha.OperStatus_DISCOVERED,
1292 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001293 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001295 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001296 }
mpagenkoe4782082021-11-25 12:04:26 +00001297 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001298 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001299 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001300 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001301 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1302 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1303 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1304 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001305}
1306
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301307// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1308//
1309// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001310func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001311 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001312 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001314
1315 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001316 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001317 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1319 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001320 }
1321
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001322 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001323 var inactiveImageID uint16
1324 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1325 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001326 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1327 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001328 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001329 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001330 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001331 if err == nil {
1332 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1333 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001335 }
1336 } else {
1337 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001338 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001339 }
mpagenko15ff4a52021-03-02 10:09:20 +00001340 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001341 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001342 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001343 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1344 dh.upgradeCanceled = true
1345 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1346 }
mpagenko38662d02021-08-11 09:45:19 +00001347 //no effort spent anymore for the old API to automatically cancel and restart the download
1348 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001349 }
mpagenko15ff4a52021-03-02 10:09:20 +00001350 } else {
1351 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001352 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001353 }
1354 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001355 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1356 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001357 }
1358 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001359}
1360
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301361// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001362// after the OnuImage has been downloaded to the adapter, called in background
1363func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001365
1366 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001367 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001368 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001369 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001370 return
1371 }
1372
1373 var inactiveImageID uint16
1374 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1375 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001376 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001377
mpagenko59862f02021-10-11 08:53:18 +00001378 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001379 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001380 // but must be still locked at calling createOnuUpgradeFsm
1381 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1382 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1383 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001384 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1385 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001387 //flush the remove upgradeFsmChan channel
1388 select {
1389 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001390 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001391 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001392 }
mpagenko59862f02021-10-11 08:53:18 +00001393 dh.lockUpgradeFsm.Unlock()
1394 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1395 dh.upgradeCanceled = true
1396 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1397 }
mpagenko38662d02021-08-11 09:45:19 +00001398 select {
1399 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001400 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001401 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1402 return
1403 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001404 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001405 }
mpagenko59862f02021-10-11 08:53:18 +00001406 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001407 }
mpagenko38662d02021-08-11 09:45:19 +00001408
1409 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001410 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001411 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001412 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001413 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001414 if err == nil {
1415 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1416 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1417 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001418 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001419 return
1420 }
mpagenko38662d02021-08-11 09:45:19 +00001421 } else {
1422 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001424 }
1425 return
1426 }
1427 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001428 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001429}
1430
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301431// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001432func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1433 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001434 var err error
1435 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1436 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1437 // 2.) activation of the inactive image
1438
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001439 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001440 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001441 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1442 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001443 }
1444 dh.lockUpgradeFsm.RLock()
1445 if dh.pOnuUpradeFsm != nil {
1446 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001448 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001449 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1450 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 }
mpagenko59862f02021-10-11 08:53:18 +00001452 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1453 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1454 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1455 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001456 // use the OnuVendor identification from this device for the internal unique name
1457 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001458 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001459 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001460 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001461 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001462 "device-id": dh.DeviceID, "error": err})
1463 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 }
mpagenko183647c2021-06-08 15:25:04 +00001465 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001466 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001467 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001468 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001469 } //else
1470 dh.lockUpgradeFsm.RUnlock()
1471
1472 // 2.) check if requested image-version equals the inactive one and start its activation
1473 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1474 var inactiveImageID uint16
1475 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1476 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001477 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1478 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001479 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001480 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001481 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001482 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001483 if err == nil {
1484 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1485 inactiveImageID, aCommitRequest); err != nil {
1486 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001487 "device-id": dh.DeviceID, "error": err})
1488 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001489 }
1490 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001492 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001493 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001494 } //else
1495 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001496 "device-id": dh.DeviceID, "error": err})
1497 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001498}
1499
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301500// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001501func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1502 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001503 var err error
1504 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1505 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1506 // 2.) commitment of the active image
1507
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001509 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001510 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1511 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001512 }
1513 dh.lockUpgradeFsm.RLock()
1514 if dh.pOnuUpradeFsm != nil {
1515 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001516 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001517 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1519 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001520 }
mpagenko59862f02021-10-11 08:53:18 +00001521 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1522 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1523 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1524 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001525 // use the OnuVendor identification from this device for the internal unique name
1526 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001527 // 1.) check a started upgrade process and relay the commitment request to it
1528 // the running upgrade may be based either on the imageIdentifier (started from download)
1529 // or on the imageVersion (started from pure activation)
1530 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1531 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001532 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001533 "device-id": dh.DeviceID, "error": err})
1534 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001535 }
mpagenko183647c2021-06-08 15:25:04 +00001536 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001538 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001539 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001540 } //else
1541 dh.lockUpgradeFsm.RUnlock()
1542
mpagenko183647c2021-06-08 15:25:04 +00001543 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001544 var activeImageID uint16
1545 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1546 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001547 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1548 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001549 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001550 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001551 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001552 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001553 if err == nil {
1554 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1555 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001556 "device-id": dh.DeviceID, "error": err})
1557 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001558 }
1559 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001560 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001561 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001562 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001563 } //else
1564 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001565 "device-id": dh.DeviceID, "error": err})
1566 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001567}
1568
mpagenkoaa3afe92021-05-21 16:20:58 +00001569func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001570 aVersion string) *voltha.ImageState {
1571 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001572 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001573 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001574 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001575 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1576 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1577 if aVersion == dh.pLastUpgradeImageState.Version {
1578 pImageState = dh.pLastUpgradeImageState
1579 } else { //state request for an image version different from last processed image version
1580 pImageState = &voltha.ImageState{
1581 Version: aVersion,
1582 //we cannot state something concerning this version
1583 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1584 Reason: voltha.ImageState_NO_ERROR,
1585 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1586 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001587 }
1588 }
mpagenko38662d02021-08-11 09:45:19 +00001589 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001590}
1591
1592func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1593 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001594 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001595 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001596 dh.lockUpgradeFsm.RLock()
1597 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001598 dh.lockUpgradeFsm.RUnlock()
1599 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001600 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001601 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1602 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1603 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1604 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1605 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1606 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001607 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1608 dh.upgradeCanceled = true
1609 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1610 }
mpagenko45586762021-10-01 08:30:22 +00001611 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001612 } else {
mpagenko45586762021-10-01 08:30:22 +00001613 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001614 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1615 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1616 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1617 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1618 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1619 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001620 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1621 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001622 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1623 //an abort request to a not active upgrade processing can be used to reset the device upgrade states completely
mpagenkoaa3afe92021-05-21 16:20:58 +00001624 }
1625}
1626
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001627func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1628
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001629 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001630
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001631 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001632 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001633 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1634 pDevEntry.MutexOnuImageStatus.Lock()
1635 pDevEntry.POnuImageStatus = onuImageStatus
1636 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001637
1638 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001639 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001640 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1641 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001642 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1643 pDevEntry.MutexOnuImageStatus.Lock()
1644 pDevEntry.POnuImageStatus = nil
1645 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001646 return images, err
1647}
1648
Himani Chawla6d2ae152020-09-02 13:11:20 +05301649// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650// #####################################################################################
1651
1652// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301653// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001656 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1657 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658}
1659
1660// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001663 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001664 var err error
1665
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001666 // populate what we know. rest comes later after mib sync
1667 dh.device.Root = false
1668 dh.device.Vendor = "OpenONU"
1669 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001671 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001672
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001674
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 if !dh.IsReconciling() {
1676 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001677 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1678 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1679 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301680 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001681 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301682 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001684 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001685
Himani Chawla4d908332020-08-31 12:30:20 +05301686 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001687 dh.ponPortNumber = dh.device.ParentPortNo
1688
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001689 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1690 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1691 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001692 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001693 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301694 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695
1696 /*
1697 self._pon = PonPort.create(self, self._pon_port_number)
1698 self._pon.add_peer(self.parent_id, self._pon_port_number)
1699 self.logger.debug('adding-pon-port-to-agent',
1700 type=self._pon.get_port().type,
1701 admin_state=self._pon.get_port().admin_state,
1702 oper_status=self._pon.get_port().oper_status,
1703 )
1704 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001705 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301706 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001707 var ponPortNo uint32 = 1
1708 if dh.ponPortNumber != 0 {
1709 ponPortNo = dh.ponPortNumber
1710 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001712 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001713 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001714 PortNo: ponPortNo,
1715 Label: fmt.Sprintf("pon-%d", ponPortNo),
1716 Type: voltha.Port_PON_ONU,
1717 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301718 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001719 PortNo: ponPortNo}}, // Peer port is parent's port number
1720 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001721 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001722 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001723 e.Cancel(err)
1724 return
1725 }
1726 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301727 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001729 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001730}
1731
1732// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001733func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001734
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001735 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001736 var err error
1737 /*
1738 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1739 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1740 return nil
1741 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001743 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001744 e.Cancel(err)
1745 return
1746 }
1747
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001748 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001749 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001750 // reconcilement will be continued after mib download is done
1751 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001752
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001753 /*
1754 ############################################################################
1755 # Setup Alarm handler
1756 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1757 device.serial_number)
1758 ############################################################################
1759 # Setup PM configuration for this device
1760 # Pass in ONU specific options
1761 kwargs = {
1762 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1763 'heartbeat': self.heartbeat,
1764 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1765 }
1766 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1767 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1768 self.logical_device_id, device.serial_number,
1769 grouped=True, freq_override=False, **kwargs)
1770 pm_config = self._pm_metrics.make_proto()
1771 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1772 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1773 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1774
1775 # Note, ONU ID and UNI intf set in add_uni_port method
1776 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1777 ani_ports=[self._pon])
1778
1779 # Code to Run OMCI Test Action
1780 kwargs_omci_test_action = {
1781 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1782 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1783 }
1784 serial_number = device.serial_number
1785 self._test_request = OmciTestRequest(self.core_proxy,
1786 self.omci_agent, self.device_id,
1787 AniG, serial_number,
1788 self.logical_device_id,
1789 exclusive=False,
1790 **kwargs_omci_test_action)
1791
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001792 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001793 else:
1794 self.logger.info('onu-already-activated')
1795 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001796
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001797 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001798}
1799
1800// doStateConnected get the device info and update to voltha core
1801// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301802//
1803// voltha-openolt-adapter/adaptercore/device_handler.go
1804// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001806
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001807 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301808 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001809 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001810 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001811}
1812
1813// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001815
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001816 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301817 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001818 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001819 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001820
1821 /*
1822 // Synchronous call to update device state - this method is run in its own go routine
1823 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1824 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001825 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 +00001826 return err
1827 }
1828 return nil
1829 */
1830}
1831
1832// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001833func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001834
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001835 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836 var err error
1837
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001838 device := dh.device
1839 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001840 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001841 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001842 e.Cancel(err)
1843 return
1844 }
1845
1846 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001847 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848 /*
1849 // Update the all ports state on that device to disable
1850 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001851 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001852 return er
1853 }
1854
1855 //Update the device oper state and connection status
1856 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1857 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1858 dh.device = cloned
1859
1860 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001861 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862 return er
1863 }
1864
1865 //get the child device for the parent device
1866 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1867 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001868 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001869 return err
1870 }
1871 for _, onuDevice := range onuDevices.Items {
1872
1873 // Update onu state as down in onu adapter
1874 onuInd := oop.OnuIndication{}
1875 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001876 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001877 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1878 if er != nil {
1879 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001880 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001881 //Do not return here and continue to process other ONUs
1882 }
1883 }
1884 // * Discovered ONUs entries need to be cleared , since after OLT
1885 // is up, it starts sending discovery indications again* /
1886 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001887 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001888 return nil
1889 */
Himani Chawla4d908332020-08-31 12:30:20 +05301890 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001891 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001892 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001893}
1894
Himani Chawla6d2ae152020-09-02 13:11:20 +05301895// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001896// #################################################################################
1897
1898// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301899// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001900
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301901// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001902func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001903 dh.lockDevice.RLock()
1904 pOnuDeviceEntry := dh.pOnuOmciDevice
1905 if aWait && pOnuDeviceEntry == nil {
1906 //keep the read sema short to allow for subsequent write
1907 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001908 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001909 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1910 // so it might be needed to wait here for that event with some timeout
1911 select {
1912 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001913 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001914 return nil
1915 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001916 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001917 // if written now, we can return the written value without sema
1918 return dh.pOnuOmciDevice
1919 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001920 }
mpagenko3af1f032020-06-10 08:53:41 +00001921 dh.lockDevice.RUnlock()
1922 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001923}
1924
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301925// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001926func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1927 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001928 dh.lockDevice.Lock()
1929 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001930 dh.pOnuOmciDevice = apDeviceEntry
1931 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001932 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301933 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001934 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001935}
1936
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301937// addOnuDeviceEntry creates a new ONU device or returns the existing
Himani Chawla6d2ae152020-09-02 13:11:20 +05301938func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001939 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001940
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001942 if deviceEntry == nil {
1943 /* costum_me_map in python code seems always to be None,
1944 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1945 /* also no 'clock' argument - usage open ...*/
1946 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1948 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1949 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1950 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1951 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001952 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001954 // fire deviceEntry ready event to spread to possibly waiting processing
1955 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001956 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001957 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001958 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001959 }
1960 // might be updated with some error handling !!!
1961 return nil
1962}
1963
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001965 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001966 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1967
1968 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001969
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001970 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001971 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1973 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001974 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05301975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001976 if !dh.IsReconciling() {
1977 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001979 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001980 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001983
khenaidoo42dcdfd2021-10-19 17:34:12 -04001984 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001985 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001986 OperStatus: voltha.OperStatus_ACTIVATING,
1987 ConnStatus: voltha.ConnectStatus_REACHABLE,
1988 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001989 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001990 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001991 }
1992 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301993 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001994 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001995
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001996 pDevEntry.MutexPersOnuConfig.RLock()
1997 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1998 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 logger.Debugw(ctx, "reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002000 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002001 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302002
2003 //VOL-4965: Recover previously Activating ONU during reconciliation.
2004 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2005 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2006 log.Fields{"device-id": dh.DeviceID})
2007 pDevEntry.MutexPersOnuConfig.Lock()
2008 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2009 pDevEntry.MutexPersOnuConfig.Unlock()
2010 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002011 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002012 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002013 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002014 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002015 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2016 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2017 // in python code it looks as the started onu_omci_device might have been updated with some new instance state of the core device
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002018 // but I would not know why, and the go code anyway does not work with the device directly anymore in the mib.OnuDeviceEntry
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002019 // so let's just try to keep it simple ...
2020 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002022 if err != nil || device == nil {
2023 //TODO: needs to handle error scenarios
2024 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2025 return errors.New("Voltha Device not found")
2026 }
2027 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002028
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002029 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002030 return err
mpagenko3af1f032020-06-10 08:53:41 +00002031 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002032 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002033
2034 /* this might be a good time for Omci Verify message? */
2035 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002036 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002037 dh.device.Id, pDevEntry.PDevOmciCC, false,
mpagenko900ee4b2020-10-12 11:56:34 +00002038 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002039 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002040
2041 /* give the handler some time here to wait for the OMCi verification result
2042 after Timeout start and try MibUpload FSM anyway
2043 (to prevent stopping on just not supported OMCI verification from ONU) */
2044 select {
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002045 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002046 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002047 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002048 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002049 }
2050
2051 /* In py code it looks earlier (on activate ..)
2052 # Code to Run OMCI Test Action
2053 kwargs_omci_test_action = {
2054 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2055 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2056 }
2057 serial_number = device.serial_number
2058 self._test_request = OmciTestRequest(self.core_proxy,
2059 self.omci_agent, self.device_id,
2060 AniG, serial_number,
2061 self.logical_device_id,
2062 exclusive=False,
2063 **kwargs_omci_test_action)
2064 ...
2065 # Start test requests after a brief pause
2066 if not self._test_request_started:
2067 self._test_request_started = True
2068 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2069 reactor.callLater(tststart, self._test_request.start_collector)
2070
2071 */
2072 /* which is then: in omci_test_request.py : */
2073 /*
2074 def start_collector(self, callback=None):
2075 """
2076 Start the collection loop for an adapter if the frequency > 0
2077
2078 :param callback: (callable) Function to call to collect PM data
2079 """
2080 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2081 if callback is None:
2082 callback = self.perform_test_omci
2083
2084 if self.lc is None:
2085 self.lc = LoopingCall(callback)
2086
2087 if self.default_freq > 0:
2088 self.lc.start(interval=self.default_freq / 10)
2089
2090 def perform_test_omci(self):
2091 """
2092 Perform the initial test request
2093 """
2094 ani_g_entities = self._device.configuration.ani_g_entities
2095 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2096 is not None else None
2097 self._entity_id = ani_g_entities_ids[0]
2098 self.logger.info('perform-test', entity_class=self._entity_class,
2099 entity_id=self._entity_id)
2100 try:
2101 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2102 result = yield self._device.omci_cc.send(frame)
2103 if not result.fields['omci_message'].fields['success_code']:
2104 self.logger.info('Self-Test Submitted Successfully',
2105 code=result.fields[
2106 'omci_message'].fields['success_code'])
2107 else:
2108 raise TestFailure('Test Failure: {}'.format(
2109 result.fields['omci_message'].fields['success_code']))
2110 except TimeoutError as e:
2111 self.deferred.errback(failure.Failure(e))
2112
2113 except Exception as e:
2114 self.logger.exception('perform-test-Error', e=e,
2115 class_id=self._entity_class,
2116 entity_id=self._entity_id)
2117 self.deferred.errback(failure.Failure(e))
2118
2119 */
2120
2121 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002122 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002123
mpagenko1cc3cb42020-07-27 15:24:38 +00002124 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2125 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2126 * 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 +05302127 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002128 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002129 //call MibUploadFSM - transition up to state UlStInSync
2130 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002131 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002132 if pMibUlFsm.Is(mib.UlStDisabled) {
2133 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2134 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2135 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302136 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002137 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302138 //Determine ONU status and start/re-start MIB Synchronization tasks
2139 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002140 if pDevEntry.IsNewOnu() {
2141 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2142 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2143 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002144 }
Himani Chawla4d908332020-08-31 12:30:20 +05302145 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002146 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2147 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2148 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302149 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002150 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002151 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002152 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002154 "device-id": dh.DeviceID})
2155 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002156 }
2157 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002158 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2159 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002160 }
2161 return nil
2162}
2163
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002164func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002165 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002166 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002167 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302168 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002169
mpagenko900ee4b2020-10-12 11:56:34 +00002170 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2171 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2172 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002173 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002174 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002175 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002176 // abort: system behavior is just unstable ...
2177 return err
2178 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002179 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 _ = 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 +00002181
2182 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002183 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002184 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002185 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002186 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2187 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002188 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002189 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002190
2191 //TODO!!! remove existing traffic profiles
2192 /* from py code, if TP's exist, remove them - not yet implemented
2193 self._tp = dict()
2194 # Let TP download happen again
2195 for uni_id in self._tp_service_specific_task:
2196 self._tp_service_specific_task[uni_id].clear()
2197 for uni_id in self._tech_profile_download_done:
2198 self._tech_profile_download_done[uni_id].clear()
2199 */
2200
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002201 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002202
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002203 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002204
mpagenkoe4782082021-11-25 12:04:26 +00002205 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002206 // abort: system behavior is just unstable ...
2207 return err
2208 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002210 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002211 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002213 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2214 OperStatus: voltha.OperStatus_DISCOVERED,
2215 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002216 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002218 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002219 // abort: system behavior is just unstable ...
2220 return err
2221 }
2222 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002223 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002224 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002225 return nil
2226}
2227
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002228func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002229 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2230 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2231 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2232 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002233 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002234
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002235 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002236 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002237 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2238 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002239 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002240 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002241 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002242 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002243 pDevEntry.MutexOnuImageStatus.RLock()
2244 if pDevEntry.POnuImageStatus != nil {
2245 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002246 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002247 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002248
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002249 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002250 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002251 }
2252 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002253 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002254 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002255 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002256 }
mpagenko101ac942021-11-16 15:01:29 +00002257 //stop any deviceHandler reconcile processing (if running)
2258 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002259 //port lock/unlock FSM's may be active
2260 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002261 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002262 }
2263 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002264 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002265 }
2266 //techProfile related PonAniConfigFsm FSM may be active
2267 if dh.pOnuTP != nil {
2268 // should always be the case here
2269 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002270 if dh.pOnuTP.PAniConfigFsm != nil {
2271 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2272 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002273 }
mpagenko900ee4b2020-10-12 11:56:34 +00002274 }
2275 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002276 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002277 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002278 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002279 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002280 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002281 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002282 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002283 } else {
2284 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002285 }
2286 }
2287 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002288 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002289 // Stop collector routine
2290 dh.stopCollector <- true
2291 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002292 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302293 dh.stopAlarmManager <- true
2294 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002295 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002296 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002297 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302298
Girish Gowdrae95687a2021-09-08 16:30:58 -07002299 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2300
mpagenko80622a52021-02-09 16:53:23 +00002301 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002302 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002303 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002304 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002306 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002307 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002308 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2309 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2310 // (even though it may also run into direct cancellation, a bit hard to verify here)
2311 // so don't set 'dh.upgradeCanceled = true' here!
2312 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2313 }
mpagenko38662d02021-08-11 09:45:19 +00002314 }
mpagenko80622a52021-02-09 16:53:23 +00002315
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002317 return nil
2318}
2319
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002320func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2321 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 +05302322
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002323 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002324 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002325 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002327 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002328 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002329 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002330
mpagenkoa40e99a2020-11-17 13:50:39 +00002331 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2332 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2333 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2334 * disable/enable toggling here to allow traffic
2335 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2336 * like the py comment says:
2337 * # start by locking all the unis till mib sync and initial mib is downloaded
2338 * # this way we can capture the port down/up events when we are ready
2339 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302340
mpagenkoa40e99a2020-11-17 13:50:39 +00002341 // Init Uni Ports to Admin locked state
2342 // *** should generate UniLockStateDone event *****
2343 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002344 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002345 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002346 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002347 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002348 }
2349}
2350
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002351func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2352 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302353 /* Mib download procedure -
2354 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2355 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002356 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002357 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002358 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002359 return
2360 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002361 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302362 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 if pMibDlFsm.Is(mib.DlStDisabled) {
2364 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2365 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 +05302366 // maybe try a FSM reset and then again ... - TODO!!!
2367 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002368 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002370 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2371 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302372 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002373 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302374 //Begin MIB data download (running autonomously)
2375 }
2376 }
2377 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302380 // maybe try a FSM reset and then again ... - TODO!!!
2381 }
2382 /***** Mib download started */
2383 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302385 }
2386}
2387
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002388func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302389 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002390 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2391 if pDevEntry == nil {
2392 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2393 return
2394 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002395 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002396 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002397 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002398 // update device info in core
2399 pDevEntry.MutexPersOnuConfig.RLock()
2400 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2401 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2402 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2403 pDevEntry.MutexPersOnuConfig.RUnlock()
2404 dh.logicalDeviceID = dh.DeviceID
2405 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2406 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2407 }
2408 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002409 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2410 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2411 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2412 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002413 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002415 ConnStatus: voltha.ConnectStatus_REACHABLE,
2416 OperStatus: voltha.OperStatus_ACTIVE,
2417 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302418 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302420 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002421 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302422 }
2423 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302424 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002425 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302426 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002427 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002428
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002429 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002430 var waitForOmciProcessor sync.WaitGroup
2431 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002432 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002433 go dh.StartCollector(ctx, &waitForOmciProcessor)
2434 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002435 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002436 if !dh.GetAlarmManagerIsRunning(ctx) {
2437 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002438 }
2439
Girish Gowdrae95687a2021-09-08 16:30:58 -07002440 // Start flow handler routines per UNI
2441 for _, uniPort := range dh.uniEntityMap {
2442 // only if this port was enabled for use by the operator at startup
2443 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2444 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2445 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2446 }
2447 }
2448 }
2449
Girish Gowdrae0140f02021-02-02 16:55:09 -08002450 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002451 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002452 // There is no way we should be landing here, but if we do then
2453 // there is nothing much we can do about this other than log error
2454 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2455 }
2456
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002457 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002458
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002459 pDevEntry.MutexPersOnuConfig.RLock()
2460 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2461 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302462 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002463 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002464 dh.mutexForDisableDeviceRequested.Lock()
2465 dh.disableDeviceRequested = true
2466 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002467 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002468 // reconcilement will be continued after ani config is done
2469 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002470 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002471 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002472 dh.mutexForDisableDeviceRequested.RLock()
2473 if !dh.disableDeviceRequested {
2474 if dh.pUnlockStateFsm == nil {
2475 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2476 } else { //UnlockStateFSM already init
2477 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2478 dh.runUniLockFsm(ctx, false)
2479 }
2480 dh.mutexForDisableDeviceRequested.RUnlock()
2481 } else {
2482 dh.mutexForDisableDeviceRequested.RUnlock()
2483 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002484 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302485 }
2486}
2487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002488func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2489 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302490
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 if !dh.IsReconciling() {
2492 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002493 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2495 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002496 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002497 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002498 return
2499 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002500 pDevEntry.MutexPersOnuConfig.Lock()
2501 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2502 pDevEntry.MutexPersOnuConfig.Unlock()
2503 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002504 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002505 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002506 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302507 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302508 logger.Info(ctx, "reconciling - don't notify core that onu went to active but trigger tech profile config",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002510 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302511
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002512 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302513
Himani Chawla26e555c2020-08-31 12:30:20 +05302514 }
2515}
2516
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002518 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002520
mpagenko44bd8362021-11-15 11:40:05 +00002521 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002522 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002523 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002524 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002525 OperStatus: voltha.OperStatus_UNKNOWN,
2526 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002527 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002528 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002529 }
2530
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002532 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002533 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002534
2535 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002537
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002538 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002539 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002540 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002541 return
2542 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543 pDevEntry.MutexPersOnuConfig.Lock()
2544 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2545 pDevEntry.MutexPersOnuConfig.Unlock()
2546 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002547 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002548 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002549 }
mpagenko900ee4b2020-10-12 11:56:34 +00002550}
2551
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002554 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002555 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002557 ConnStatus: voltha.ConnectStatus_REACHABLE,
2558 OperStatus: voltha.OperStatus_ACTIVE,
2559 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002560 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002562 }
2563
dbainbri4d3a0dc2020-12-02 00:33:42 +00002564 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002565 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002566 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002567 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002568
2569 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002573 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002575 return
2576 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 pDevEntry.MutexPersOnuConfig.Lock()
2578 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2579 pDevEntry.MutexPersOnuConfig.Unlock()
2580 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002581 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002583 }
mpagenko900ee4b2020-10-12 11:56:34 +00002584}
2585
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002586func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2587 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2588 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002589 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002590 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002591 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002592 OperStatus: voltha.OperStatus_FAILED,
2593 }); err != nil {
2594 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2595 }
2596}
2597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002598func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2599 if devEvent == cmn.OmciAniConfigDone {
2600 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002601 // attention: the device reason update is done based on ONU-UNI-Port related activity
2602 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002604 // which may be the case from some previous activity even on this UNI Port (but also other UNI ports)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002605 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302606 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002607 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002608 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2609 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2610 dh.mutexReconcilingFirstPassFlag.Lock()
2611 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302612 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002613 dh.reconcilingFirstPass = false
2614 go dh.ReconcileDeviceFlowConfig(ctx)
2615 }
2616 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002617 }
2618 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002619 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002620 // attention: the device reason update is done based on ONU-UNI-Port related activity
2621 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002623 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2624 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002625 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002626 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302627}
2628
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002629func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002630 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002631 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302632 // attention: the device reason update is done based on ONU-UNI-Port related activity
2633 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302634
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002635 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2636 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002637 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002638 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002639 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002640 }
2641 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002642 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002643 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002644 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002645 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302646 }
mpagenkof1fc3862021-02-16 10:09:52 +00002647
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002648 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002649 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002651 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002652 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002653 }
2654 } else {
2655 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002657 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302658}
2659
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302660// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002661func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302662 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002664 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002665 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002666 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002667 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002668 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002669 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002670 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002671 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002672 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002673 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002674 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002676 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002677 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002678 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002679 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002680 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002681 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002682 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002683 case cmn.UniEnableStateFailed:
2684 {
2685 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2686 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002687 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002688 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002689 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002690 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002692 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002693 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002694 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002696 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002697 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002698 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002699 default:
2700 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002701 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002702 }
2703 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002704}
2705
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002706func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002707 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002708 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302709 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002710 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002711 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002712 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302713 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002715 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002716 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002717 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002718 //store UniPort with the System-PortNumber key
2719 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002721 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002722 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002723 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002724 } //error logging already within UniPort method
2725 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302726 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002727 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002728 }
2729 }
2730}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002731
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2733 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002734 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002735 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002736 return
2737 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002738 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002739 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002740 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2741 for _, mgmtEntityID := range pptpInstKeys {
2742 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002743 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002744 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2745 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002746 }
2747 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002748 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002749 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002751 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2752 for _, mgmtEntityID := range veipInstKeys {
2753 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002754 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002755 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2756 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002757 }
2758 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002760 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002761 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002762 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2763 for _, mgmtEntityID := range potsInstKeys {
2764 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002765 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002766 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2767 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002768 }
2769 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002770 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002771 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002772 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002773 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002774 return
2775 }
2776
mpagenko2c3f6c52021-11-23 11:22:10 +00002777 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2778 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2779 // also for the POTS ports, so we include them already for future usage - should anyway do no great harm
Girish Gowdrae95687a2021-09-08 16:30:58 -07002780 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2781 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2782 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002783 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2784 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002785 for i := 0; i < int(uniCnt); i++ {
2786 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002787 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002788 }
2789}
2790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002791// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2792func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002793 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302794 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002795 // with following remark:
2796 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2797 // # load on the core
2798
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002799 // lock_ports(false) as done in py code here is shifted to separate call from device event processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002800
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002801 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002802 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2804 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2805 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2806 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002807 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002808 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002809 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002810 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002811 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002812 PortNo: port.PortNo,
2813 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002814 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815 logger.Errorw(ctx, "port-state-update-failed", log.Fields{"error": err, "port-no": uniPort.PortNo, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002816 }
2817 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002818 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302819 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002820 }
mpagenko3af1f032020-06-10 08:53:41 +00002821 }
2822 }
2823}
2824
2825// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002826func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2827 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002828 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2829 for uniNo, uniPort := range dh.uniEntityMap {
2830 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002831
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002832 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2833 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2834 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2835 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002836 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002837 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002838 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002840 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002841 PortNo: port.PortNo,
2842 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002843 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002844 logger.Errorw(ctx, "port-state-update-failed", log.Fields{"error": err, "port-no": uniPort.PortNo, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002845 }
2846 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002847 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302848 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002849 }
2850
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002851 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002852 }
2853}
2854
2855// ONU_Active/Inactive announcement on system KAFKA bus
2856// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002857func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002858 var de voltha.DeviceEvent
2859 eventContext := make(map[string]string)
2860 //Populating event context
2861 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002862 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002863 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002864 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002865 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002866 return //TODO with VOL-3045: rw-core is unresponsive: report error and/or perform self-initiated onu-reset?
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002867 }
2868 oltSerialNumber := parentDevice.SerialNumber
2869
2870 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2871 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2872 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302873 eventContext["olt-serial-number"] = oltSerialNumber
2874 eventContext["device-id"] = aDeviceID
2875 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002876 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002877 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2878 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002879 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2880 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002881 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2882 deviceEntry.MutexPersOnuConfig.RUnlock()
2883 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002885 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2886 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2887 } else {
2888 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2889 log.Fields{"device-id": aDeviceID})
2890 return
2891 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002892
2893 /* Populating device event body */
2894 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302895 de.ResourceId = aDeviceID
2896 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002897 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2898 de.Description = fmt.Sprintf("%s Event - %s - %s",
2899 cEventObjectType, cOnuActivatedEvent, "Raised")
2900 } else {
2901 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2902 de.Description = fmt.Sprintf("%s Event - %s - %s",
2903 cEventObjectType, cOnuActivatedEvent, "Cleared")
2904 }
2905 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302906 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002907 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302908 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002909 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302910 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302911 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002912}
2913
Himani Chawla4d908332020-08-31 12:30:20 +05302914// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002915func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2916 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002917 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302918 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002920 sFsmName = "LockStateFSM"
2921 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002923 sFsmName = "UnLockStateFSM"
2924 }
mpagenko3af1f032020-06-10 08:53:41 +00002925
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002926 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002927 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002928 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002929 return
2930 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002931 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002932 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302933 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002934 dh.pLockStateFsm = pLSFsm
2935 } else {
2936 dh.pUnlockStateFsm = pLSFsm
2937 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002938 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002939 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002941 }
2942}
2943
2944// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002946 /* Uni Port lock/unlock procedure -
2947 ***** should run via 'adminDone' state and generate the argument requested event *****
2948 */
2949 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302950 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002951 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002952 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2953 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2955 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002956 }
2957 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002959 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2960 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2962 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002963 }
2964 }
2965 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002966 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2967 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002968 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002969 // maybe try a FSM reset and then again ... - TODO!!!
2970 } else {
2971 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002972 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002973 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002974 }
2975 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002976 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002978 // maybe try a FSM reset and then again ... - TODO!!!
2979 }
2980 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002982 // maybe try a FSM reset and then again ... - TODO!!!
2983 }
2984}
2985
mpagenko80622a52021-02-09 16:53:23 +00002986// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002987// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002988func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002990 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002991 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002992 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002993 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002994 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002995 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002996 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002997 sFsmName, chUpgradeFsm)
2998 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002999 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003000 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003001 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3002 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003003 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003004 // maybe try a FSM reset and then again ... - TODO!!!
3005 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
3006 }
mpagenko59862f02021-10-11 08:53:18 +00003007 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003008 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3009 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003010 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3011 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003012 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003014 } else {
3015 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003017 // maybe try a FSM reset and then again ... - TODO!!!
3018 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
3019 }
3020 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003022 // maybe try a FSM reset and then again ... - TODO!!!
3023 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
3024 }
3025 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003026 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003027 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
3028 }
3029 return nil
3030}
3031
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003032// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3033func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003034 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003036 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003037 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3038 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003039 dh.pLastUpgradeImageState = apImageState
3040 dh.lockUpgradeFsm.Unlock()
3041 //signal upgradeFsm removed using non-blocking channel send
3042 select {
3043 case dh.upgradeFsmChan <- struct{}{}:
3044 default:
3045 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003046 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003047 }
mpagenko80622a52021-02-09 16:53:23 +00003048}
3049
mpagenko15ff4a52021-03-02 10:09:20 +00003050// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3051func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003052 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003053 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003054 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003055 return
3056 }
3057
3058 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003059 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003060 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003061 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3062 dh.lockUpgradeFsm.RUnlock()
3063 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3064 return
3065 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003066 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003067 if pUpgradeStatemachine != nil {
3068 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3069 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003070 UpgradeState := pUpgradeStatemachine.Current()
3071 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3072 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3073 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003074 // here no need to update the upgrade image state to activated as the state will be immediately be set to committing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003075 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003076 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3077 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003078 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003079 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003080 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003081 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3082 dh.upgradeCanceled = true
3083 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3084 }
mpagenko15ff4a52021-03-02 10:09:20 +00003085 return
3086 }
mpagenko59862f02021-10-11 08:53:18 +00003087 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003088 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3089 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003090 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003091 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003092 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3093 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003094 return
3095 }
3096 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003098 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003099 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3100 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003101 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3102 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003103 return
3104 }
3105 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003106 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003107 }
3108 } else {
3109 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003110 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003111 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3112 dh.upgradeCanceled = true
3113 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3114 }
mpagenko1f8e8822021-06-25 14:10:21 +00003115 }
mpagenko15ff4a52021-03-02 10:09:20 +00003116 return
3117 }
mpagenko59862f02021-10-11 08:53:18 +00003118 dh.lockUpgradeFsm.RUnlock()
3119 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3120 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003121 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3122 dh.upgradeCanceled = true
3123 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3124 }
mpagenko59862f02021-10-11 08:53:18 +00003125 return
3126 }
3127 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3128 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3129 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3130 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3131 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3132 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3133 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003134 }
mpagenko15ff4a52021-03-02 10:09:20 +00003135 }
3136 }
3137 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003139 }
mpagenko59862f02021-10-11 08:53:18 +00003140 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003141}
3142
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303143// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003144func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003145
3146 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003148 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003149 kvbackend := &db.Backend{
3150 Client: dh.pOpenOnuAc.kvClient,
3151 StoreType: dh.pOpenOnuAc.KVStoreType,
3152 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003153 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003154 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3155 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003156
mpagenkoaf801632020-07-03 10:00:42 +00003157 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003158}
khenaidoo7d3c5582021-08-11 18:09:44 -04003159func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303160 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003161
mpagenkodff5dda2020-08-28 11:52:01 +00003162 for _, field := range flow.GetOfbFields(apFlowItem) {
3163 switch field.Type {
3164 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3165 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003166 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003167 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3168 }
mpagenko01e726e2020-10-23 09:45:29 +00003169 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003170 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3171 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303172 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303174 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3175 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003176 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3177 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003178 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303180 return
mpagenkodff5dda2020-08-28 11:52:01 +00003181 }
3182 }
mpagenko01e726e2020-10-23 09:45:29 +00003183 */
mpagenkodff5dda2020-08-28 11:52:01 +00003184 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3185 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303186 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003187 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303188 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003189 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303190 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003191 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003192 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303193 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003194 }
3195 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3196 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303197 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003198 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303199 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003200 }
3201 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3202 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003203 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003204 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3205 }
3206 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3207 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003208 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003209 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3210 }
3211 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3212 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003213 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003214 "IPv4-DST": field.GetIpv4Dst()})
3215 }
3216 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3217 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003218 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003219 "IPv4-SRC": field.GetIpv4Src()})
3220 }
3221 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3222 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003223 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003224 "Metadata": field.GetTableMetadata()})
3225 }
3226 /*
3227 default:
3228 {
3229 //all other entires ignored
3230 }
3231 */
3232 }
3233 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303234}
mpagenkodff5dda2020-08-28 11:52:01 +00003235
khenaidoo7d3c5582021-08-11 18:09:44 -04003236func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003237 for _, action := range flow.GetActions(apFlowItem) {
3238 switch action.Type {
3239 /* not used:
3240 case of.OfpActionType_OFPAT_OUTPUT:
3241 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003243 "Output": action.GetOutput()})
3244 }
3245 */
3246 case of.OfpActionType_OFPAT_PUSH_VLAN:
3247 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003248 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003249 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3250 }
3251 case of.OfpActionType_OFPAT_SET_FIELD:
3252 {
3253 pActionSetField := action.GetSetField()
3254 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003255 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003256 "OxcmClass": pActionSetField.Field.OxmClass})
3257 }
3258 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303259 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003260 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303261 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003262 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303263 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003264 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303265 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003266 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003267 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003268 "Type": pActionSetField.Field.GetOfbField().Type})
3269 }
3270 }
3271 /*
3272 default:
3273 {
3274 //all other entires ignored
3275 }
3276 */
3277 }
3278 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303279}
3280
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303281// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003282func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003283 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303284 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3285 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303286 var loSetPcp uint8
3287 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303288 var loIPProto uint32
3289 /* the TechProfileId is part of the flow Metadata - compare also comment within
3290 * OLT-Adapter:openolt_flowmgr.go
3291 * Metadata 8 bytes:
3292 * Most Significant 2 Bytes = Inner VLAN
3293 * Next 2 Bytes = Tech Profile ID(TPID)
3294 * Least Significant 4 Bytes = Port ID
3295 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3296 * subscriber related flows.
3297 */
3298
dbainbri4d3a0dc2020-12-02 00:33:42 +00003299 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303300 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003301 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003302 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003303 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303304 }
mpagenko551a4d42020-12-08 18:09:20 +00003305 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003306 loCookie := apFlowItem.GetCookie()
3307 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303308 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003309 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303310 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303311
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303312 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003313 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303314 if loIPProto == 2 {
3315 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3316 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003317 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003318 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303319 return nil
3320 }
mpagenko01e726e2020-10-23 09:45:29 +00003321 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003322 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003323
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303324 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3325 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003326 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003327 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003328 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3329 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3330 //TODO!!: Use DeviceId within the error response to rwCore
3331 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003332 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003333 }
3334 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003335 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003336 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303337 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3338 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3339 loSetVlan = loMatchVlan
3340 logger.Debugw(ctx, "flow-add, double tagged case, set setvlan to matchvlan ", log.Fields{"device-id": dh.DeviceID, "loSetVlan": loSetVlan, "loMatchVlan": loMatchVlan})
mpagenkodff5dda2020-08-28 11:52:01 +00003341 } else {
3342 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3343 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3344 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303345 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003346 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003347 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003348 }
mpagenko9a304ea2020-12-16 15:54:01 +00003349
khenaidoo42dcdfd2021-10-19 17:34:12 -04003350 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003351 if apFlowMetaData != nil {
3352 meter = apFlowMetaData.Meters[0]
3353 }
mpagenkobc4170a2021-08-17 16:42:10 +00003354 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3355 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3356 // when different rules are requested concurrently for the same uni
3357 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3358 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3359 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003360 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3361 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003362 //SetUniFlowParams() may block on some rule that is suspended-to-add
3363 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003364 // Also the error is returned to caller via response channel
3365 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303366 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003367 dh.lockVlanConfig.RUnlock()
3368 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003369 return
mpagenkodff5dda2020-08-28 11:52:01 +00003370 }
mpagenkobc4170a2021-08-17 16:42:10 +00003371 dh.lockVlanConfig.RUnlock()
3372 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003373 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303374 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003375 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003376 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003377 if err != nil {
3378 *respChan <- err
3379 }
mpagenko01e726e2020-10-23 09:45:29 +00003380}
3381
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303382// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003383func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003384 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3385 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3386 //no extra check is done on the rule parameters
3387 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3388 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3389 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3390 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003391 // - 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 +00003392 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003393 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003394
3395 /* TT related temporary workaround - should not be needed anymore
3396 for _, field := range flow.GetOfbFields(apFlowItem) {
3397 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3398 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003399 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003400 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3401 if loIPProto == 2 {
3402 // 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 +00003403 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003404 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003405 return nil
3406 }
3407 }
3408 } //for all OfbFields
3409 */
3410
mpagenko9a304ea2020-12-16 15:54:01 +00003411 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003412 dh.lockVlanConfig.RLock()
3413 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003414 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3415 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003416 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3417 return
mpagenko01e726e2020-10-23 09:45:29 +00003418 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003419 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003420 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003421 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003422 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003423 // Push response on the response channel
3424 if respChan != nil {
3425 // Do it in a non blocking fashion, so that in case the flow handler routine has shutdown for any reason, we do not block here
3426 select {
3427 case *respChan <- nil:
3428 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3429 default:
3430 }
3431 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003432 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003433}
3434
Himani Chawla26e555c2020-08-31 12:30:20 +05303435// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003436// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003437// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003438func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303439 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003440 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003441
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003442 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003443 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003444 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3445 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003446 }
3447
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003448 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3449 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303450 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003451 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003452 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3453 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003454 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3455 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003456 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003457 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3458 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003459 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3460 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003461 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003462 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303463 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003464 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3466 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003467 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003468 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3470 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003471 }
3472 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003473 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003474 "device-id": dh.DeviceID})
3475 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003476 }
3477 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003478 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3480 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003481 }
3482 return nil
3483}
3484
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303485// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003486// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003487func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003488 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003490 for _, uniPort := range dh.uniEntityMap {
3491 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003492 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003493 pCurrentUniPort = uniPort
3494 break //found - end search loop
3495 }
3496 }
3497 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003498 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003500 return
3501 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003502 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003503}
3504
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303505// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003506func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003507 //TODO!! verify and start pending flow configuration
3508 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3509 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303510 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003511 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003512 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003513 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003514 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003516 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003517 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003518 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003519 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3520 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003521 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003522 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003523 } else {
3524 /***** UniVlanConfigFsm continued */
3525 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003526 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3527 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003528 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003529 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3530 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003531 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003532 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003533 } else {
3534 /***** UniVlanConfigFsm continued */
3535 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003536 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3537 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003538 }
mpagenkodff5dda2020-08-28 11:52:01 +00003539 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003540 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003541 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3542 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003543 }
3544 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003545 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3547 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003548 }
3549 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003550 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003551 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003552 }
mpagenkof1fc3862021-02-16 10:09:52 +00003553 } else {
3554 dh.lockVlanConfig.RUnlock()
3555 }
mpagenkodff5dda2020-08-28 11:52:01 +00003556}
3557
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303558// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003559// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003560func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003561 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003562 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003563 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003564 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003566 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003567}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003568
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303569// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003570func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003571 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3572 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3573 // obviously then parallel processing on the cancel must be avoided
3574 // deadline context to ensure completion of background routines waited for
3575 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3576 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3577 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3578
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003579 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003580 var wg sync.WaitGroup
3581 wg.Add(1) // for the 1 go routine to finish
3582
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003583 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003584 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3585
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003586 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003587}
3588
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303589// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3590// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003591func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3592 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303595 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003596 return nil
3597 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003598 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003599
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003600 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003601 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003602 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3603 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003604 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003605 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003606
mpagenkof1fc3862021-02-16 10:09:52 +00003607 if aWriteToKvStore {
3608 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3609 }
3610 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003611}
3612
dbainbri4d3a0dc2020-12-02 00:33:42 +00003613func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003614 defer cancel() //ensure termination of context (may be pro forma)
3615 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003616 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003617 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003618}
3619
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303620// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3621//
3622// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00003623func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3624 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3625 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3626 dh.mutexDeviceReason.Lock()
3627 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003628 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003629 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003630 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003631 DeviceId: dh.DeviceID,
3632 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003633 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003634 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003635 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003636 return err
3637 }
mpagenkoe4782082021-11-25 12:04:26 +00003638 } else {
3639 logger.Debugf(ctx, "update reason in core not requested: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003640 }
mpagenkoe4782082021-11-25 12:04:26 +00003641 dh.deviceReason = deviceReason
3642 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3643 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003644 return nil
3645}
3646
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003647func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3648 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003649 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003650 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3651 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003652 }
mpagenkof1fc3862021-02-16 10:09:52 +00003653 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003654}
3655
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003656// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003657// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003658func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3659 dh.lockDevice.RLock()
3660 defer dh.lockDevice.RUnlock()
3661 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003663 }
3664 return 0, errors.New("error-fetching-uni-port")
3665}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003666
3667// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003668func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3669 var errorsList []error
3670 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 -08003671
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003672 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3673 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3674 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3675
3676 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3677 // successfully.
3678 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3679 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3680 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003681 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003682 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003683 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003684 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003685 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003686}
3687
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003688func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3689 var err error
3690 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003691 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003692
3693 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003695 errorsList = append(errorsList, err)
3696 }
3697 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003698 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003699
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003700 return errorsList
3701}
3702
3703func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3704 var err error
3705 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003706 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003707 // Check if group metric related config is updated
3708 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3710 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3711 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003712
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003713 if ok && m.Frequency != v.GroupFreq {
3714 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003715 errorsList = append(errorsList, err)
3716 }
3717 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003718 if ok && m.Enabled != v.Enabled {
3719 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003720 errorsList = append(errorsList, err)
3721 }
3722 }
3723 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003724 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003725 return errorsList
3726}
3727
3728func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3729 var err error
3730 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003731 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003732 // Check if standalone metric related config is updated
3733 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003734 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3735 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3736 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003737
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003738 if ok && m.Frequency != v.SampleFreq {
3739 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003740 errorsList = append(errorsList, err)
3741 }
3742 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003743 if ok && m.Enabled != v.Enabled {
3744 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003745 errorsList = append(errorsList, err)
3746 }
3747 }
3748 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003749 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003750 return errorsList
3751}
3752
3753// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003754func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003755 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003756
3757 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003758 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303759 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003760 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003761 // Initialize the next metric collection time.
3762 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3763 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003764 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003765 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05303766 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
3767 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08003768 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05303769
Girish Gowdrae09a6202021-01-12 18:10:59 -08003770 select {
3771 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003772 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003773 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003774 // Stop the L2 PM FSM
3775 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3777 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3778 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003779 }
3780 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003781 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003782 }
3783 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003784 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3785 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003786 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003787 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3788 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003789 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003790
Girish Gowdrae09a6202021-01-12 18:10:59 -08003791 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05303792 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003793 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3794 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3795 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3796 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003797 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003798 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003799 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003800 } else {
3801 if dh.pmConfigs.Grouped { // metrics are managed as a group
3802 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003803 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003804
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003805 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3806 // 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 -08003807 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003808 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3809 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003810 }
3811 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003812 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3813 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3814 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3815 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003816 }
3817 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003818 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003819
3820 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003821 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3822 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3823 // 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 -08003824 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003825 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3826 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003827 }
3828 }
3829 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003830 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3831 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3832 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3833 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003834 }
3835 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003836 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003837 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003838 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003839 } */
3840 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003841 }
3842 }
3843}
kesavandfdf77632021-01-26 23:40:33 -05003844
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003845func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003846
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003847 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3848 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003849}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003850
Himani Chawla43f95ff2021-06-03 00:24:12 +05303851func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3852 if dh.pOnuMetricsMgr == nil {
3853 return &extension.SingleGetValueResponse{
3854 Response: &extension.GetValueResponse{
3855 Status: extension.GetValueResponse_ERROR,
3856 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3857 },
3858 }
3859 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303860 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303861 return resp
3862}
3863
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003864func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3865
3866 var err error
3867 var pDevOmciCC *cmn.OmciCC
3868 if dh.pOnuOmciDevice == nil {
3869 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3870 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3871 } else {
3872 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3873 if pDevOmciCC == nil {
3874 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3875 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3876 }
3877 }
3878 if err != nil {
3879 return &extension.SingleGetValueResponse{
3880 Response: &extension.GetValueResponse{
3881 Status: extension.GetValueResponse_ERROR,
3882 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3883 },
3884 },
3885 err
3886 }
3887 return pDevOmciCC.GetOmciCounters(), nil
3888}
3889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003890func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3891 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003892 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003893 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003894 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003895}
3896
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003897func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003898 var pAdapterFsm *cmn.AdapterFsm
3899 //note/TODO!!: might be that access to all these specific FSM pointers need a semaphore protection as well, cmp lockUpgradeFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003900 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003901 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003902 {
mpagenkofbf577d2021-10-12 11:44:33 +00003903 if dh.pOnuOmciDevice != nil {
3904 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3905 } else {
3906 return true //FSM not active - so there is no activity on omci
3907 }
mpagenkof1fc3862021-02-16 10:09:52 +00003908 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003909 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003910 {
mpagenkofbf577d2021-10-12 11:44:33 +00003911 if dh.pOnuOmciDevice != nil {
3912 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3913 } else {
3914 return true //FSM not active - so there is no activity on omci
3915 }
mpagenkof1fc3862021-02-16 10:09:52 +00003916 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003917 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003918 {
mpagenkofbf577d2021-10-12 11:44:33 +00003919 if dh.pLockStateFsm != nil {
3920 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3921 } else {
3922 return true //FSM not active - so there is no activity on omci
3923 }
mpagenkof1fc3862021-02-16 10:09:52 +00003924 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003926 {
mpagenkofbf577d2021-10-12 11:44:33 +00003927 if dh.pUnlockStateFsm != nil {
3928 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3929 } else {
3930 return true //FSM not active - so there is no activity on omci
3931 }
mpagenkof1fc3862021-02-16 10:09:52 +00003932 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003933 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003934 {
mpagenkofbf577d2021-10-12 11:44:33 +00003935 if dh.pOnuMetricsMgr != nil {
3936 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003937 } else {
3938 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003939 }
3940 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003941 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003942 {
3943 dh.lockUpgradeFsm.RLock()
3944 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003945 if dh.pOnuUpradeFsm != nil {
3946 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3947 } else {
3948 return true //FSM not active - so there is no activity on omci
3949 }
mpagenko80622a52021-02-09 16:53:23 +00003950 }
mpagenkof1fc3862021-02-16 10:09:52 +00003951 default:
3952 {
3953 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003954 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003955 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003956 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003957 }
mpagenkofbf577d2021-10-12 11:44:33 +00003958 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3959 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3960 }
3961 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003962}
3963
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003964func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3965 for _, v := range dh.pOnuTP.PAniConfigFsm {
3966 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003967 return false
3968 }
3969 }
3970 return true
3971}
3972
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003973func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003974 dh.lockVlanConfig.RLock()
3975 defer dh.lockVlanConfig.RUnlock()
3976 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003977 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003978 return false
3979 }
3980 }
3981 return true //FSM not active - so there is no activity on omci
3982}
3983
3984func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3985 dh.lockVlanConfig.RLock()
3986 defer dh.lockVlanConfig.RUnlock()
3987 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003988 if v.PAdaptFsm.PFsm != nil {
3989 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003990 return true //there is at least one VLAN FSM with some active configuration
3991 }
3992 }
3993 }
3994 return false //there is no VLAN FSM with some active configuration
3995}
3996
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003997func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003998 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3999 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4000 return false
4001 }
4002 }
4003 // a further check is done to identify, if at least some data traffic related configuration exists
4004 // 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])
4005 return dh.checkUserServiceExists(ctx)
4006}
4007
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004008func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304009 logger.Info(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004010 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004011 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004012 // TODO: fatal error reset ONU, delete deviceHandler!
4013 return
4014 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004015 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4016 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004017}
4018
4019func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4020 dh.mutexCollectorFlag.Lock()
4021 dh.collectorIsRunning = flagValue
4022 dh.mutexCollectorFlag.Unlock()
4023}
4024
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004025func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004026 dh.mutexCollectorFlag.RLock()
4027 flagValue := dh.collectorIsRunning
4028 dh.mutexCollectorFlag.RUnlock()
4029 return flagValue
4030}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304031
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304032func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4033 dh.mutextAlarmManagerFlag.Lock()
4034 dh.alarmManagerIsRunning = flagValue
4035 dh.mutextAlarmManagerFlag.Unlock()
4036}
4037
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004038func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304039 dh.mutextAlarmManagerFlag.RLock()
4040 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004041 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304042 dh.mutextAlarmManagerFlag.RUnlock()
4043 return flagValue
4044}
4045
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004046func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004047 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304048
4049 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004050 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304051 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304052 if stop := <-dh.stopAlarmManager; stop {
4053 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304054 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05304055 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004056 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4057 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304058 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304059 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004060 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4061 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304062 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304063 }
4064}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004065
Girish Gowdrae95687a2021-09-08 16:30:58 -07004066func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4067 dh.mutexFlowMonitoringRoutineFlag.Lock()
4068 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004069 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004070 dh.isFlowMonitoringRoutineActive[uniID] = flag
4071}
4072
4073func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4074 dh.mutexFlowMonitoringRoutineFlag.RLock()
4075 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4076 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004077 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004078 return dh.isFlowMonitoringRoutineActive[uniID]
4079}
4080
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004081func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304082 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004083
Maninder7961d722021-06-16 22:10:28 +05304084 connectStatus := voltha.ConnectStatus_UNREACHABLE
4085 operState := voltha.OperStatus_UNKNOWN
4086
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004087 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004088 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004089 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004090 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004091 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004092 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304093 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004094 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4095 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4096 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4097 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4098 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4099 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4100 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4101 // However, a later refactoring of the functionality remains unaffected.
4102 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004103 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004104 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304105 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004106 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304107 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004108 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004109 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304110 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004111 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4112 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304113 operState = voltha.OperStatus_ACTIVE
4114 } else {
4115 operState = voltha.OperStatus_ACTIVATING
4116 }
4117 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004118 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4119 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4120 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304121 operState = voltha.OperStatus_DISCOVERED
4122 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004123 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004124 logger.Debugw(ctx, "Core DeviceStateUpdate",
4125 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304126 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304127 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004128 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004129 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004130 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004131 ConnStatus: connectStatus,
4132 OperStatus: operState,
4133 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304134 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004135 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304136 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004137 } else {
Maninderb5187552021-03-23 22:23:42 +05304138 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004139 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304140
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004141 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304142 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004143 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004144 } else {
4145 onuDevEntry.MutexPersOnuConfig.RLock()
4146 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4147 connectStatus = voltha.ConnectStatus_REACHABLE
4148 }
4149 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304150 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004151 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004152 }
mpagenko101ac942021-11-16 15:01:29 +00004153 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004154 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004155 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004156 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304157
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004158 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304159 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004160 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004161 } else {
4162 onuDevEntry.MutexPersOnuConfig.RLock()
4163 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4164 connectStatus = voltha.ConnectStatus_REACHABLE
4165 }
4166 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304167 }
4168
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004169 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304170
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004171 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004172 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004173 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004174 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004175 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004176
4177 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4178 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4179 } else {
4180 onuDevEntry.MutexReconciledTpInstances.Lock()
4181 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4182 onuDevEntry.MutexReconciledTpInstances.Unlock()
4183 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004184 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004185 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004186 dh.mutexReconcilingFlag.Lock()
4187 if skipOnuConfig {
4188 dh.reconciling = cSkipOnuConfigReconciling
4189 } else {
4190 dh.reconciling = cOnuConfigReconciling
4191 }
4192 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004193}
4194
mpagenko101ac942021-11-16 15:01:29 +00004195func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304196 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004197 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004198 dh.sendChReconcileFinished(success)
4199 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4200 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4201 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004202 } else {
mpagenko101ac942021-11-16 15:01:29 +00004203 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004204 }
4205}
4206
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004207func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004208 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004209 defer dh.mutexReconcilingFlag.RUnlock()
4210 return dh.reconciling != cNoReconciling
4211}
4212
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004213func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004214 dh.mutexReconcilingFlag.RLock()
4215 defer dh.mutexReconcilingFlag.RUnlock()
4216 return dh.reconciling == cSkipOnuConfigReconciling
4217}
4218
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004219func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4220 dh.mutexReconcilingFirstPassFlag.Lock()
4221 dh.reconcilingFirstPass = value
4222 dh.mutexReconcilingFirstPassFlag.Unlock()
4223}
4224
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004225func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4226 dh.mutexReconcilingReasonUpdate.Lock()
4227 dh.reconcilingReasonUpdate = value
4228 dh.mutexReconcilingReasonUpdate.Unlock()
4229}
4230
4231func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4232 dh.mutexReconcilingReasonUpdate.RLock()
4233 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4234 return dh.reconcilingReasonUpdate
4235}
4236
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004237func (dh *deviceHandler) getDeviceReason() uint8 {
4238 dh.mutexDeviceReason.RLock()
4239 value := dh.deviceReason
4240 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004241 return value
4242}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004243
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004244func (dh *deviceHandler) GetDeviceReasonString() string {
4245 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004246}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004247
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004248func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004249 dh.mutexReadyForOmciConfig.Lock()
4250 dh.readyForOmciConfig = flagValue
4251 dh.mutexReadyForOmciConfig.Unlock()
4252}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004253func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004254 dh.mutexReadyForOmciConfig.RLock()
4255 flagValue := dh.readyForOmciConfig
4256 dh.mutexReadyForOmciConfig.RUnlock()
4257 return flagValue
4258}
Maninder7961d722021-06-16 22:10:28 +05304259
4260func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004261 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304262 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004263 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304264 }
4265
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004266 logger.Debugw(ctx, "Core DeviceStateUpdate",
4267 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004268 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004269 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004270 ConnStatus: connectStatus,
4271 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4272 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304273 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004274 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304275 }
4276}
khenaidoo7d3c5582021-08-11 18:09:44 -04004277
4278/*
4279Helper functions to communicate with Core
4280*/
4281
4282func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4283 cClient, err := dh.coreClient.GetCoreServiceClient()
4284 if err != nil || cClient == nil {
4285 return nil, err
4286 }
4287 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4288 defer cancel()
4289 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4290 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4291}
4292
khenaidoo42dcdfd2021-10-19 17:34:12 -04004293func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004294 cClient, err := dh.coreClient.GetCoreServiceClient()
4295 if err != nil || cClient == nil {
4296 return err
4297 }
4298 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4299 defer cancel()
4300 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004301 logger.Debugw(subCtx, "device-updated-in-core",
4302 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004303 return err
4304}
4305
4306func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4307 cClient, err := dh.coreClient.GetCoreServiceClient()
4308 if err != nil || cClient == nil {
4309 return err
4310 }
4311 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4312 defer cancel()
4313 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004314 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4315 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004316 return err
4317}
4318
4319func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4320 cClient, err := dh.coreClient.GetCoreServiceClient()
4321 if err != nil || cClient == nil {
4322 return err
4323 }
4324 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4325 defer cancel()
4326 _, err = cClient.DeviceUpdate(subCtx, device)
4327 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4328 return err
4329}
4330
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004331func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004332 cClient, err := dh.coreClient.GetCoreServiceClient()
4333 if err != nil || cClient == nil {
4334 return err
4335 }
4336 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4337 defer cancel()
4338 _, err = cClient.PortCreated(subCtx, port)
4339 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4340 return err
4341}
4342
khenaidoo42dcdfd2021-10-19 17:34:12 -04004343func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004344 cClient, err := dh.coreClient.GetCoreServiceClient()
4345 if err != nil || cClient == nil {
4346 return err
4347 }
4348 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4349 defer cancel()
4350 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004351 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"device-id": dh.device.Id, "port-state": portState, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004352 return err
4353}
4354
khenaidoo42dcdfd2021-10-19 17:34:12 -04004355func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004356 cClient, err := dh.coreClient.GetCoreServiceClient()
4357 if err != nil || cClient == nil {
4358 return err
4359 }
4360 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4361 defer cancel()
4362 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004363 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"device-id": dh.device.Id, "reason": reason, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004364 return err
4365}
4366
4367/*
4368Helper functions to communicate with parent adapter
4369*/
4370
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004371func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4372 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4373
4374 var request = ia.TechProfileInstanceRequestMessage{
4375 DeviceId: dh.DeviceID,
4376 TpInstancePath: aTpPath,
4377 ParentDeviceId: dh.parentID,
4378 ParentPonPort: dh.device.ParentPortNo,
4379 OnuId: dh.device.ProxyAddress.OnuId,
4380 UniId: uint32(aUniID),
4381 }
4382
4383 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004384 if err != nil || pgClient == nil {
4385 return nil, err
4386 }
4387 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4388 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004389 logger.Debugw(subCtx, "get-tech-profile-instance",
4390 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004391 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004392}
4393
Girish Gowdrae95687a2021-09-08 16:30:58 -07004394// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4395// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4396func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4397 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4398 dh.setFlowMonitoringIsRunning(uniID, true)
4399 for {
4400 select {
4401 // block on the channel to receive an incoming flow
4402 // process the flow completely before proceeding to handle the next flow
4403 case flowCb := <-dh.flowCbChan[uniID]:
4404 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304405 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004406 respChan := make(chan error)
4407 if flowCb.addFlow {
4408 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4409 } else {
4410 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4411 }
4412 // Block on response and tunnel it back to the caller
4413 *flowCb.respChan <- <-respChan
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304414 logger.Info(flowCb.ctx, "serial-flow-processor--end",
Girish Gowdrae95687a2021-09-08 16:30:58 -07004415 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4416 case <-dh.stopFlowMonitoringRoutine[uniID]:
4417 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4418 dh.setFlowMonitoringIsRunning(uniID, false)
4419 return
4420 }
4421 }
4422}
4423
kesavand011d5162021-11-25 19:21:06 +05304424func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4425 request.ParentDeviceId = dh.GetProxyAddressID()
4426 request.ChildDeviceId = dh.DeviceID
4427 request.ProxyAddress = dh.GetProxyAddress()
4428 request.ConnectStatus = common.ConnectStatus_REACHABLE
4429
4430 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4431 if err != nil || pgClient == nil {
4432 return err
4433 }
4434 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4435 defer cancel()
4436 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4437 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4438 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004439 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4440 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304441 }
4442 return err
4443}
4444
khenaidoo42dcdfd2021-10-19 17:34:12 -04004445func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004446 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4447 if err != nil || pgClient == nil {
4448 return err
4449 }
4450 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4451 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004452 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004453 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004454 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4455 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004456 if status.Code(err) == codes.Unavailable {
4457 dh.setOltAvailable(false)
4458 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004459 logger.Errorw(ctx, "omci-failure",
4460 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004461 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004462 }
4463 return err
4464}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004465
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004466func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4467 // Check if there are additional TCONT instances necessary/available
4468 pDevEntry.MutexPersOnuConfig.Lock()
4469 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4470 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4471 pDevEntry.MutexPersOnuConfig.Unlock()
4472 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4473 logger.Debugw(ctx, "checking available TCONT instances",
4474 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4475 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4476 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4477 log.Fields{"device-id": dh.device.Id})
4478 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
4479 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID))
4480 }
4481 } else {
4482 pDevEntry.MutexPersOnuConfig.Unlock()
4483 }
4484 // Check if there are enough PrioQueue instances available
4485 if dh.pOnuTP != nil {
4486 var numberOfUsPrioQueueDbInsts int
4487
4488 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4489 for _, mgmtEntityID := range queueInstKeys {
4490 if mgmtEntityID >= 0x8000 && mgmtEntityID <= 0xFFFF {
4491 numberOfUsPrioQueueDbInsts++
4492 }
4493 }
4494 // Check if there is an upstream PriorityQueue instance available for each Gem port
4495 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4496 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4497 log.Fields{"device-id": dh.DeviceID,
4498 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4499 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4500 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4501
4502 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4503 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4504 log.Fields{"device-id": dh.device.Id})
4505 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
4506 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID))
4507 }
4508 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4509 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4510 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4511 } else {
4512 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4513 log.Fields{"device-id": dh.DeviceID})
4514 }
4515 return nil
4516}
4517
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004518// GetDeviceID - TODO: add comment
4519func (dh *deviceHandler) GetDeviceID() string {
4520 return dh.DeviceID
4521}
4522
4523// GetProxyAddressID - TODO: add comment
4524func (dh *deviceHandler) GetProxyAddressID() string {
4525 return dh.device.ProxyAddress.GetDeviceId()
4526}
4527
4528// GetProxyAddressType - TODO: add comment
4529func (dh *deviceHandler) GetProxyAddressType() string {
4530 return dh.device.ProxyAddress.GetDeviceType()
4531}
4532
4533// GetProxyAddress - TODO: add comment
4534func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4535 return dh.device.ProxyAddress
4536}
4537
4538// GetEventProxy - TODO: add comment
4539func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4540 return dh.EventProxy
4541}
4542
4543// GetOmciTimeout - TODO: add comment
4544func (dh *deviceHandler) GetOmciTimeout() int {
4545 return dh.pOpenOnuAc.omciTimeout
4546}
4547
4548// GetAlarmAuditInterval - TODO: add comment
4549func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4550 return dh.pOpenOnuAc.alarmAuditInterval
4551}
4552
4553// GetDlToOnuTimeout4M - TODO: add comment
4554func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4555 return dh.pOpenOnuAc.dlToOnuTimeout4M
4556}
4557
4558// GetUniEntityMap - TODO: add comment
4559func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4560 return &dh.uniEntityMap
4561}
4562
4563// GetPonPortNumber - TODO: add comment
4564func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4565 return &dh.ponPortNumber
4566}
4567
4568// GetUniVlanConfigFsm - TODO: add comment
4569func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004570 dh.lockVlanConfig.RLock()
4571 value := dh.UniVlanConfigFsmMap[uniID]
4572 dh.lockVlanConfig.RUnlock()
4573 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004574}
4575
4576// GetOnuAlarmManager - TODO: add comment
4577func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4578 return dh.pAlarmMgr
4579}
4580
4581// GetOnuMetricsManager - TODO: add comment
4582func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4583 return dh.pOnuMetricsMgr
4584}
4585
4586// GetOnuTP - TODO: add comment
4587func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4588 return dh.pOnuTP
4589}
4590
4591// GetBackendPathPrefix - TODO: add comment
4592func (dh *deviceHandler) GetBackendPathPrefix() string {
4593 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4594}
4595
4596// GetOnuIndication - TODO: add comment
4597func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4598 return dh.pOnuIndication
4599}
4600
4601// RLockMutexDeletionInProgressFlag - TODO: add comment
4602func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4603 dh.mutexDeletionInProgressFlag.RLock()
4604}
4605
4606// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4607func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4608 dh.mutexDeletionInProgressFlag.RUnlock()
4609}
4610
4611// GetDeletionInProgress - TODO: add comment
4612func (dh *deviceHandler) GetDeletionInProgress() bool {
4613 return dh.deletionInProgress
4614}
4615
4616// GetPmConfigs - TODO: add comment
4617func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4618 return dh.pmConfigs
4619}
4620
4621// GetDeviceType - TODO: add comment
4622func (dh *deviceHandler) GetDeviceType() string {
4623 return dh.DeviceType
4624}
4625
4626// GetLogicalDeviceID - TODO: add comment
4627func (dh *deviceHandler) GetLogicalDeviceID() string {
4628 return dh.logicalDeviceID
4629}
4630
4631// GetDevice - TODO: add comment
4632func (dh *deviceHandler) GetDevice() *voltha.Device {
4633 return dh.device
4634}
4635
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004636func (dh *deviceHandler) setOltAvailable(value bool) {
4637 dh.mutexOltAvailable.Lock()
4638 dh.oltAvailable = value
4639 dh.mutexOltAvailable.Unlock()
4640}
4641
4642// IsOltAvailable - TODO: add comment
4643func (dh *deviceHandler) IsOltAvailable() bool {
4644 dh.mutexOltAvailable.RLock()
4645 defer dh.mutexOltAvailable.RUnlock()
4646 return dh.oltAvailable
4647}
4648
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004649// GetMetricsEnabled - TODO: add comment
4650func (dh *deviceHandler) GetMetricsEnabled() bool {
4651 return dh.pOpenOnuAc.MetricsEnabled
4652}
4653
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004654// GetExtendedOmciSupportEnabled - TODO: add comment
4655func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4656 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4657}
4658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004659// InitPmConfigs - TODO: add comment
4660func (dh *deviceHandler) InitPmConfigs() {
4661 dh.pmConfigs = &voltha.PmConfigs{}
4662}
4663
4664// GetUniPortMask - TODO: add comment
4665func (dh *deviceHandler) GetUniPortMask() int {
4666 return dh.pOpenOnuAc.config.UniPortMask
4667}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004668
4669func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4670 tpPathFound := false
4671 for _, tpPath := range aTpPathMap {
4672 if tpPath != "" {
4673 tpPathFound = true
4674 }
4675 }
4676 return tpPathFound
4677}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004678
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304679func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
4680 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
4681 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4682 return resp
4683}
4684
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004685// PrepareForGarbageCollection - remove references to prepare for garbage collection
4686func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4687 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4688
4689 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4690 // first let the objects rest for some time to give all asynchronously started
4691 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004692 time.Sleep(2 * time.Second)
4693
4694 if dh.pOnuOmciDevice != nil {
4695 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4696 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4697 // reset handling (even in future coding), request monitoring is canceled here one last time to
4698 // be sure that all corresponding go routines are terminated
4699 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4700 }
4701 }
4702 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004703
4704 if dh.pOnuTP != nil {
4705 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4706 }
4707 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004708 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
4709 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07004710 select {
4711 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4712 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4713 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4714 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004715 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07004716 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004717 }
4718 if dh.pAlarmMgr != nil {
4719 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4720 }
4721 if dh.pSelfTestHdlr != nil {
4722 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4723 }
4724 if dh.pLockStateFsm != nil {
4725 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4726 }
4727 if dh.pUnlockStateFsm != nil {
4728 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4729 }
4730 if dh.pOnuUpradeFsm != nil {
4731 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4732 }
4733 if dh.pOnuOmciDevice != nil {
4734 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4735 }
4736 for k, v := range dh.UniVlanConfigFsmMap {
4737 v.PrepareForGarbageCollection(ctx, aDeviceID)
4738 delete(dh.UniVlanConfigFsmMap, k)
4739 }
4740 dh.pOnuOmciDevice = nil
4741 dh.pOnuTP = nil
4742 dh.pOnuMetricsMgr = nil
4743 dh.pAlarmMgr = nil
4744 dh.pSelfTestHdlr = nil
4745 dh.pLockStateFsm = nil
4746 dh.pUnlockStateFsm = nil
4747 dh.pOnuUpradeFsm = nil
4748}