blob: 641bd28d9b34ea532ce798938e4f7b292907329b [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package core provides the utility for onu devices, flows and statistics
18package 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 Hildebrandt0f9b88d2020-04-20 13:33:25 +000058)
59
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060const (
mpagenko101ac942021-11-16 15:01:29 +000061 //constants for reconcile flow check channel
62 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
63 cWaitReconcileFlowAbortOnError = 0xFFFE
64 cWaitReconcileFlowNoActivity = 0xFFFF
65)
66
67const (
68 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000069 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000071
mpagenko1cc3cb42020-07-27 15:24:38 +000072const (
mpagenko44bd8362021-11-15 11:40:05 +000073 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
74 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
75 // as long as such is not available by the libraries - use this workaround
76 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
77)
78
79const (
mpagenko1cc3cb42020-07-27 15:24:38 +000080 // events of Device FSM
81 devEvDeviceInit = "devEvDeviceInit"
82 devEvGrpcConnected = "devEvGrpcConnected"
83 devEvGrpcDisconnected = "devEvGrpcDisconnected"
84 devEvDeviceUpInd = "devEvDeviceUpInd"
85 devEvDeviceDownInd = "devEvDeviceDownInd"
86)
87const (
88 // states of Device FSM
89 devStNull = "devStNull"
90 devStDown = "devStDown"
91 devStInit = "devStInit"
92 devStConnected = "devStConnected"
93 devStUp = "devStUp"
94)
95
Holger Hildebrandt24d51952020-05-04 14:03:42 +000096//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
97const (
Himani Chawla4d908332020-08-31 12:30:20 +053098 pon = voltha.EventSubCategory_PON
99 //olt = voltha.EventSubCategory_OLT
100 //ont = voltha.EventSubCategory_ONT
101 //onu = voltha.EventSubCategory_ONU
102 //nni = voltha.EventSubCategory_NNI
103 //service = voltha.EventCategory_SERVICE
104 //security = voltha.EventCategory_SECURITY
105 equipment = voltha.EventCategory_EQUIPMENT
106 //processing = voltha.EventCategory_PROCESSING
107 //environment = voltha.EventCategory_ENVIRONMENT
108 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000109)
110
111const (
112 cEventObjectType = "ONU"
113)
114const (
115 cOnuActivatedEvent = "ONU_ACTIVATED"
116)
117
mpagenkof1fc3862021-02-16 10:09:52 +0000118type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000119 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000120 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000123var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
124 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
125 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
126 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
128 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
129 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
130 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
131 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000132}
133
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000134const (
135 cNoReconciling = iota
136 cOnuConfigReconciling
137 cSkipOnuConfigReconciling
138)
139
Girish Gowdrae95687a2021-09-08 16:30:58 -0700140// FlowCb is the flow control block containing flow add/delete information along with a response channel
141type FlowCb struct {
142 ctx context.Context // Flow handler context
143 addFlow bool // if true flow to be added, else removed
144 flowItem *of.OfpFlowStats
145 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400146 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700147 respChan *chan error // channel to report the Flow handling error
148}
149
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150//deviceHandler will interact with the ONU ? device.
151type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000152 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153 DeviceType string
154 adminState string
155 device *voltha.Device
156 logicalDeviceID string
157 ProxyAddressID string
158 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530159 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000160 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000161
khenaidoo7d3c5582021-08-11 18:09:44 -0400162 coreClient *vgrpc.Client
163 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000164
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800165 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400166 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800167
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000168 pOpenOnuAc *OpenONUAC
169 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530170 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000171 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000172 pOnuOmciDevice *mib.OnuDeviceEntry
173 pOnuTP *avcfg.OnuUniTechProf
174 pOnuMetricsMgr *pmmgr.OnuMetricsManager
175 pAlarmMgr *almgr.OnuAlarmManager
176 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000177 exitChannel chan int
178 lockDevice sync.RWMutex
179 pOnuIndication *oop.OnuIndication
180 deviceReason uint8
181 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000182 pLockStateFsm *uniprt.LockStateFsm
183 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000185 //flowMgr *OpenOltFlowMgr
186 //eventMgr *OpenOltEventMgr
187 //resourceMgr *rsrcMgr.OpenOltResourceMgr
188
189 //discOnus sync.Map
190 //onus sync.Map
191 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000192 collectorIsRunning bool
193 mutexCollectorFlag sync.RWMutex
194 stopCollector chan bool
195 alarmManagerIsRunning bool
196 mutextAlarmManagerFlag sync.RWMutex
197 stopAlarmManager chan bool
198 stopHeartbeatCheck chan bool
199 uniEntityMap cmn.OnuUniPortMap
200 mutexKvStoreContext sync.Mutex
201 lockVlanConfig sync.RWMutex
202 lockVlanAdd sync.RWMutex
203 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
204 lockUpgradeFsm sync.RWMutex
205 pOnuUpradeFsm *swupg.OnuUpgradeFsm
206 upgradeCanceled bool
207 reconciling uint8
208 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000209 reconcilingFirstPass bool
210 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000211 reconcilingReasonUpdate bool
212 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000213 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
214 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
215 reconcileExpiryComplete time.Duration
216 reconcileExpiryVlanConfig time.Duration
217 mutexReadyForOmciConfig sync.RWMutex
218 readyForOmciConfig bool
219 deletionInProgress bool
220 mutexDeletionInProgressFlag sync.RWMutex
221 pLastUpgradeImageState *voltha.ImageState
222 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700223
224 flowCbChan []chan FlowCb
225 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300226 mutexForDisableDeviceRequested sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700227 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
228 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300229 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230}
231
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400233func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530234 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400235 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400237 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000239 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.DeviceType = cloned.Type
241 dh.adminState = "up"
242 dh.device = cloned
243 dh.pOpenOnuAc = adapter
244 dh.exitChannel = make(chan int, 1)
245 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000246 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000247 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530249 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530250 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 dh.stopHeartbeatCheck = make(chan bool, 2)
252 //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 +0000253 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000255 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000256 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000257 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300258 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000260 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000261 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000262 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300263 dh.disableDeviceRequested = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000264 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000265 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
266 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
267 if rECSeconds < 2 {
268 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
269 rECSeconds = 2
270 }
271 rEVCSeconds := rECSeconds / 2
272 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000273 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000274 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000275 dh.pLastUpgradeImageState = &voltha.ImageState{
276 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
277 Reason: voltha.ImageState_UNKNOWN_ERROR,
278 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
279 }
280 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800282 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
283 dh.pmConfigs = cloned.PmConfigs
284 } /* else {
285 // will be populated when onu_metrics_mananger is initialized.
286 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800287
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 // Device related state machine
289 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000290 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000292 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
293 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
294 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
295 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
296 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 },
298 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
300 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
301 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
302 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
303 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
304 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
305 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
306 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307 },
308 )
mpagenkoaf801632020-07-03 10:00:42 +0000309
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310 return &dh
311}
312
Himani Chawla6d2ae152020-09-02 13:11:20 +0530313// start save the device to the data model
314func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000315 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000317 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318}
319
Himani Chawla4d908332020-08-31 12:30:20 +0530320/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323 logger.Debug("stopping-device-handler")
324 dh.exitChannel <- 1
325}
Himani Chawla4d908332020-08-31 12:30:20 +0530326*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327
328// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530329// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330
Girish Gowdrae0140f02021-02-02 16:55:09 -0800331//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530332func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400333 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000335 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000336 if dh.pDeviceStateFsm.Is(devStNull) {
337 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000338 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 +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())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800341 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
342 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800343 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400344 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800346 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800347 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000348 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000350 }
351
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000352}
353
khenaidoo42dcdfd2021-10-19 17:34:12 -0400354func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000355 /* 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 +0530356 //assuming omci message content is hex coded!
357 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000358 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000359 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000360 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000363 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000365 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000366 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
367 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530368 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
370 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530371}
372
khenaidoo42dcdfd2021-10-19 17:34:12 -0400373func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000375
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000377 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
379 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 if dh.pOnuTP == nil {
382 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 log.Fields{"device-id": dh.DeviceID})
385 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 if !dh.IsReadyForOmciConfig() {
388 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
389 "device-state": dh.GetDeviceReasonString()})
390 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000392 //previous state test here was just this one, now extended for more states to reject the SetRequest:
393 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
394 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530395
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000397 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
398 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 dh.pOnuTP.LockTpProcMutex()
400 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
mpagenko44bd8362021-11-15 11:40:05 +0000402 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000404 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 }
406 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800408 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000409 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
410 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800411 return err
412 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000413 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
414 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000416 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530417
Girish Gowdra50e56422021-06-01 16:46:04 -0700418 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400419 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000420 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
421 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700422 // if there has been some change for some uni TechProfilePath
423 //in order to allow concurrent calls to other dh instances we do not wait for execution here
424 //but doing so we can not indicate problems to the caller (who does what with that then?)
425 //by now we just assume straightforward successful execution
426 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
427 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530428
Girish Gowdra50e56422021-06-01 16:46:04 -0700429 // deadline context to ensure completion of background routines waited for
430 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
431 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
432 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000433
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000434 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700435
436 var wg sync.WaitGroup
437 wg.Add(1) // for the 1 go routine to finish
438 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700440 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000441 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
442 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 -0700443 return tpErr
444 }
445 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
446 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000447 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700448 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700450 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000451 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
452 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 -0700453 return kvErr
454 }
455 return nil
456 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000457 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700458 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700459 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530460 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000461 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000462 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
463 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530464 return nil
465}
466
khenaidoo42dcdfd2021-10-19 17:34:12 -0400467func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000468 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530469
470 if dh.pOnuTP == nil {
471 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000473 log.Fields{"device-id": dh.DeviceID})
474 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530476 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000477 dh.pOnuTP.LockTpProcMutex()
478 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530479
mpagenko0f543222021-11-03 16:24:14 +0000480 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
481 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
482 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000484 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485 }
486 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000487 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800488 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000489 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
490 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800491 return err
492 }
mpagenko0f543222021-11-03 16:24:14 +0000493 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
494 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000495 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000496
Mahir Gunyel9545be22021-07-04 15:53:16 -0700497 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499
Himani Chawla26e555c2020-08-31 12:30:20 +0530500}
501
khenaidoo42dcdfd2021-10-19 17:34:12 -0400502func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000503 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 +0000504
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000507 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
508 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530510 if dh.pOnuTP == nil {
511 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 log.Fields{"device-id": dh.DeviceID})
514 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 }
516
Himani Chawla26e555c2020-08-31 12:30:20 +0530517 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000518 dh.pOnuTP.LockTpProcMutex()
519 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520
mpagenko0f543222021-11-03 16:24:14 +0000521 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
522 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
523 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000525 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 }
527 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700528 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000529 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800530 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000531 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
532 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800533 return err
534 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530536
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000537 var wg sync.WaitGroup
538 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
539 dctx, cancel := context.WithDeadline(context.Background(), deadline)
540 wg.Add(1)
541 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
542 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
543 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
544 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
545 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
546 return err
547 }
548
Mahir Gunyel9545be22021-07-04 15:53:16 -0700549 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000551
Mahir Gunyel9545be22021-07-04 15:53:16 -0700552}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000553
Mahir Gunyel9545be22021-07-04 15:53:16 -0700554func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000555 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
556 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700557 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000558 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
559 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530560 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700561 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700563 resourceName = "Gem"
564 } else {
565 resourceName = "Tcont"
566 }
567
568 // deadline context to ensure completion of background routines waited for
569 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
570 dctx, cancel := context.WithDeadline(context.Background(), deadline)
571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700573
574 var wg sync.WaitGroup
575 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700577 resource, entryID, &wg)
578 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
580 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700581 return err
582 }
583
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
585 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
586 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
587 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700588 var wg2 sync.WaitGroup
589 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
590 wg2.Add(1)
591 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000592 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 +0000593 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700594 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
596 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700597 return err
598 }
599 }
600 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000601 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700602 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530603 return nil
604}
605
mpagenkodff5dda2020-08-28 11:52:01 +0000606//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400608 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400609 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700610 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
611 var errorsList []error
612 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000613 //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 +0000614 if apOfFlowChanges.ToRemove != nil {
615 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000616 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 "device-id": dh.DeviceID})
619 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700620 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000621 continue
622 }
623 flowInPort := flow.GetInPort(flowItem)
624 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000625 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
626 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700627 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000628 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000629 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000630 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000631 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000633 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000634 continue
635 } else {
636 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000637 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000638 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
639 loUniPort = uniPort
640 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000643 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700645 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000646 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000647 }
648 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000650 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
651 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700652
653 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
654 // Step1 : Fill flowControlBlock
655 // Step2 : Push the flowControlBlock to ONU channel
656 // Step3 : Wait on response channel for response
657 // Step4 : Return error value
658 startTime := time.Now()
659 respChan := make(chan error)
660 flowCb := FlowCb{
661 ctx: ctx,
662 addFlow: false,
663 flowItem: flowItem,
664 flowMetaData: nil,
665 uniPort: loUniPort,
666 respChan: &respChan,
667 }
668 dh.flowCbChan[loUniPort.UniID] <- flowCb
669 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
670 // Wait on the channel for flow handlers return value
671 retError = <-respChan
672 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
673 if retError != nil {
674 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
675 log.Fields{"device-id": dh.DeviceID, "error": retError})
676 errorsList = append(errorsList, retError)
677 continue
678 }
679 } else {
680 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
681 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000682 }
683 }
684 }
685 }
mpagenko01e726e2020-10-23 09:45:29 +0000686 if apOfFlowChanges.ToAdd != nil {
687 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
688 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000689 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000690 "device-id": dh.DeviceID})
691 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700692 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000693 continue
694 }
695 flowInPort := flow.GetInPort(flowItem)
696 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000697 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
698 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700699 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000700 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000701 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000702 } else if flowInPort == dh.ponPortNumber {
703 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000705 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000706 continue
707 } else {
708 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000709 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000710 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
711 loUniPort = uniPort
712 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000713 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000714 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000715 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000716 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700717 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000718 continue
mpagenko01e726e2020-10-23 09:45:29 +0000719 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000720 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
721 // if not, we just throw some error here to have an indication about that, if we really need to support that
722 // then we would need to create some means to activate the internal stored flows
723 // after the device gets active automatically (and still with its dependency to the TechProfile)
724 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
725 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000726 if !dh.IsReadyForOmciConfig() {
727 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
728 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700729 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
730 errorsList = append(errorsList, retError)
731 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000732 }
733
mpagenko01e726e2020-10-23 09:45:29 +0000734 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000736 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
737 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700738 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
739 // Step1 : Fill flowControlBlock
740 // Step2 : Push the flowControlBlock to ONU channel
741 // Step3 : Wait on response channel for response
742 // Step4 : Return error value
743 startTime := time.Now()
744 respChan := make(chan error)
745 flowCb := FlowCb{
746 ctx: ctx,
747 addFlow: true,
748 flowItem: flowItem,
749 flowMetaData: apFlowMetaData,
750 uniPort: loUniPort,
751 respChan: &respChan,
752 }
753 dh.flowCbChan[loUniPort.UniID] <- flowCb
754 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
755 // Wait on the channel for flow handlers return value
756 retError = <-respChan
757 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
758 if retError != nil {
759 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
760 log.Fields{"device-id": dh.DeviceID, "error": retError})
761 errorsList = append(errorsList, retError)
762 continue
763 }
764 } else {
765 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
766 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000767 }
768 }
769 }
770 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700771 if len(errorsList) > 0 {
772 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
773 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
774 }
775 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000776}
777
Himani Chawla6d2ae152020-09-02 13:11:20 +0530778//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000779//following are the expected device states after this activity:
780//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
781// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
783 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300784 dh.mutexForDisableDeviceRequested.Lock()
785 dh.disableDeviceRequested = true
786 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000787 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000788 //note that disableDevice sequences in some 'ONU active' state may yield also
789 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000790 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000791 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000792 //disable-device shall be just a UNi/ONU-G related admin state setting
793 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000794
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000795 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000796 // disable UNI ports/ONU
797 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
798 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000799 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000800 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000801 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000803 }
804 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000805 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000807 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400808 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000809 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000810 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400811 OperStatus: voltha.OperStatus_UNKNOWN,
812 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000813 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000815 }
mpagenko01e726e2020-10-23 09:45:29 +0000816 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000817
818 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000819 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000820 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300821 }
822}
823
Himani Chawla6d2ae152020-09-02 13:11:20 +0530824//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
826 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000827
mpagenkoaa3afe92021-05-21 16:20:58 +0000828 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000829 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
830 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
831 // for real ONU's that should have nearly no influence
832 // Note that for real ONU's there is anyway a problematic situation with following sequence:
833 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
834 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
835 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000837
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000838 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000839 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300840 dh.mutexForDisableDeviceRequested.Lock()
841 dh.disableDeviceRequested = false
842 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000843 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000844 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000845 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000846 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000848 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300849}
850
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000852 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000853
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000854 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 return
858 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000860 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000862 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000864 }
mpagenko101ac942021-11-16 15:01:29 +0000865 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000866 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000867 }
Himani Chawla4d908332020-08-31 12:30:20 +0530868 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000869 pDevEntry.MutexPersOnuConfig.RLock()
870 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
871 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
872 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
873 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
874 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000876}
877
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000878func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000879 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000880
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000881 continueWithFlowConfig := false
882
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000885 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000886 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
887 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000888 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 dh.pOnuTP.LockTpProcMutex()
890 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000891
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000893 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000894 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
895 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000897 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000898 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
899 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000900 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000901 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700902 techProfsFound := false
903 techProfInstLoadFailed := false
904outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000905 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000906 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000907 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000908 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000909 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000910 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000911 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000912 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000913 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
914 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000915 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000916 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000917 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700918 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000919 var iaTechTpInst ia.TechProfileDownloadMessage
920 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800921 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000922 pDevEntry.MutexReconciledTpInstances.RLock()
923 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
924 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000925 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000926 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700927 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000928 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700929 break outerLoop
930 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000931 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000932 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700933 var tpInst tech_profile.TechProfileInstance
934 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400935 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700936 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000937 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000938 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700939 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000940 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700942 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
943 break outerLoop
944 }
945
Girish Gowdra041dcb32020-11-16 16:54:30 -0800946 // deadline context to ensure completion of background routines waited for
947 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
948 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000951 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800952 var wg sync.WaitGroup
953 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000955 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
957 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700958 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
959 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800960 }
mpagenko2dc896e2021-08-02 12:03:59 +0000961 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000962 if len(uniData.PersFlowParams) != 0 {
963 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000964 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000966 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 } // for all UNI entries from SOnuPersistentData
968 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
969 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000970 }
mpagenko2dc896e2021-08-02 12:03:59 +0000971
972 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
973 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000974
975 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000976}
977
978func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
979 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
980 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000981 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000983 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000984 return
985 }
mpagenko2dc896e2021-08-02 12:03:59 +0000986 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000987 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000988 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700989 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000991 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000992 }
mpagenko2dc896e2021-08-02 12:03:59 +0000993 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000994 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000995 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000996 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000997 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000998}
999
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001000func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1001 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001002
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001003 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001004 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001005 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001006 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001007 return
1008 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001009
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 pDevEntry.MutexPersOnuConfig.RLock()
1011 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1012 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001015 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001016 return
1017 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001019 var uniVlanConfigEntries []uint8
1020 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1021
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001022 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001023 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1024 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001025 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001026 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001027 continue
1028 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001029 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001030 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001032 // It doesn't make sense to configure any flows if no TPs are available
1033 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001034 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1036 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001037 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001038 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001039
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001041 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001042 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001043 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1045 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001046 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001047 return
1048 }
mpagenko101ac942021-11-16 15:01:29 +00001049 //needed to split up function due to sca complexity
1050 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1051
mpagenko2dc896e2021-08-02 12:03:59 +00001052 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001053 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1055 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001056 // this can't be used as global finished reconciling flag because
1057 // assumes is getting called before the state machines for the last flow is completed,
1058 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1060 } // for all UNI entries from SOnuPersistentData
1061 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001062
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001063 if !flowsFound {
1064 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001065 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001066 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001067 return
1068 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001069 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1070 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1071 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1072 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1073 log.Fields{"device-id": dh.DeviceID})
1074 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1075 if pDevEntry != nil {
1076 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001077 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001078 } else {
1079 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1080 log.Fields{"device-id": dh.DeviceID})
1081 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1082 if pDevEntry != nil {
1083 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1084 }
1085 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001086 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001087 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001088}
1089
mpagenko101ac942021-11-16 15:01:29 +00001090func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1091 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1092 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1093 flowsProcessed := 0
1094 lastFlowToReconcile := false
1095 loUniID := apUniPort.UniID
1096 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001097 if !(*apFlowsFound) {
1098 *apFlowsFound = true
1099 syncChannel := make(chan struct{})
1100 // start go routine with select() on reconciling vlan config channel before
1101 // starting vlan config reconciling process to prevent loss of any signal
1102 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1103 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1104 //block until the wait routine is really blocked on channel input
1105 // in order to prevent to early ready signal from VlanConfig processing
1106 <-syncChannel
1107 }
1108 if flowsProcessed == len(aPersFlowParam)-1 {
1109 var uniAdded bool
1110 lastFlowToReconcile = true
1111 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1112 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001113 }
1114 }
mpagenko101ac942021-11-16 15:01:29 +00001115 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1116 "device-id": dh.DeviceID, "uni-id": loUniID,
1117 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1118 dh.lockVlanConfig.Lock()
1119 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1120 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1121 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301122 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 +00001123 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1124 }
1125 } else {
1126 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301127 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301128 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001129 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1130 }
1131 }
1132 dh.lockVlanConfig.Unlock()
1133 flowsProcessed++
1134 } //for all flows of this UNI
1135}
1136
1137//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1138// and decrements the according handler wait group waiting for these indications
1139func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1140 waitGroup *cmn.WaitGroupWithTimeOut) {
1141 var reconciledUniVlanConfigEntries []uint8
1142 var appended bool
1143 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1144 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1145 "device-id": dh.DeviceID, "expiry": expiry})
1146 // indicate blocking on channel now to the caller
1147 aSyncChannel <- struct{}{}
1148 for {
1149 select {
1150 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1151 switch uniIndication {
1152 // no activity requested (should normally not be received) - just continue waiting
1153 case cWaitReconcileFlowNoActivity:
1154 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1155 case cWaitReconcileFlowAbortOnError:
1156 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1157 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1158 return
1159 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1160 case cWaitReconcileFlowAbortOnSuccess:
1161 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1162 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1163 return
1164 // this should be a valid UNI vlan config done indication
1165 default:
1166 if uniIndication < platform.MaxUnisPerOnu {
1167 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1168 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1169 if reconciledUniVlanConfigEntries, appended =
1170 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1171 waitGroup.Done()
1172 }
1173 } else {
1174 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1175 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1176 }
1177 } //switch uniIndication
1178
1179 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1180 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1181 log.Fields{"device-id": dh.DeviceID})
1182 return
1183 }
1184 }
1185}
1186
1187func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1188 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1189}
1190
1191func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1192 for _, ele := range slice {
1193 if ele == val {
1194 return slice, false
1195 }
1196 }
1197 return append(slice, val), true
1198}
1199
1200// sendChReconcileFinished - sends true or false on reconcileFinish channel
1201func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1202 if dh != nil { //if the object still exists (might have been already deleted in background)
1203 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1204 select {
1205 case dh.chReconcilingFinished <- success:
1206 default:
1207 }
1208 }
1209}
1210
1211// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1212func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1213 if dh != nil { //if the object still exists (might have been already deleted in background)
1214 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1215 select {
1216 case dh.chUniVlanConfigReconcilingDone <- value:
1217 default:
1218 }
1219 }
1220}
1221
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001223 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001224
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001225 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001226 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001227 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001229 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001230 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001231
1232 // deadline context to ensure completion of background routines waited for
1233 //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 +05301234 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001236
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001238
1239 var wg sync.WaitGroup
1240 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001243
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001244 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001245 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001246}
1247
mpagenko15ff4a52021-03-02 10:09:20 +00001248//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1249// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001250// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001251//was and is called in background - error return does not make sense
1252func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001253 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001254 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001256 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001257 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001258 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301259 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001260 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001261 return
Himani Chawla4d908332020-08-31 12:30:20 +05301262 }
mpagenko01e726e2020-10-23 09:45:29 +00001263
1264 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001265 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001266
mpagenko44bd8362021-11-15 11:40:05 +00001267 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001268 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001269 // 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 -04001270 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001271 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001272 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001273 OperStatus: voltha.OperStatus_DISCOVERED,
1274 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001275 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001276 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001277 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001278 }
mpagenkoe4782082021-11-25 12:04:26 +00001279 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001280 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001281 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001283 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1284 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1285 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1286 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001287}
1288
mpagenkoc8bba412021-01-15 15:38:44 +00001289//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001290// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001291func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001293 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001295
1296 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001297 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001298 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1300 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001301 }
1302
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001304 var inactiveImageID uint16
1305 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1306 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001307 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1308 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001309 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001311 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001312 if err == nil {
1313 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1314 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001315 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001316 }
1317 } else {
1318 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001320 }
mpagenko15ff4a52021-03-02 10:09:20 +00001321 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001322 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001323 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001324 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1325 dh.upgradeCanceled = true
1326 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1327 }
mpagenko38662d02021-08-11 09:45:19 +00001328 //no effort spent anymore for the old API to automatically cancel and restart the download
1329 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001330 }
mpagenko15ff4a52021-03-02 10:09:20 +00001331 } else {
1332 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001334 }
1335 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1337 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001338 }
1339 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001340}
1341
mpagenkoc26d4c02021-05-06 14:27:57 +00001342//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1343// after the OnuImage has been downloaded to the adapter, called in background
1344func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001345 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001346
1347 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001348 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001349 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001351 return
1352 }
1353
1354 var inactiveImageID uint16
1355 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1356 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001357 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001358
mpagenko59862f02021-10-11 08:53:18 +00001359 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001360 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001361 // but must be still locked at calling createOnuUpgradeFsm
1362 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1363 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1364 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001365 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1366 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001367 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001368 //flush the remove upgradeFsmChan channel
1369 select {
1370 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001371 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001372 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001373 }
mpagenko59862f02021-10-11 08:53:18 +00001374 dh.lockUpgradeFsm.Unlock()
1375 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1376 dh.upgradeCanceled = true
1377 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1378 }
mpagenko38662d02021-08-11 09:45:19 +00001379 select {
1380 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001382 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1383 return
1384 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001385 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001386 }
mpagenko59862f02021-10-11 08:53:18 +00001387 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001388 }
mpagenko38662d02021-08-11 09:45:19 +00001389
1390 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001391 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001392 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001393 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001394 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001395 if err == nil {
1396 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1397 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1398 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001399 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001400 return
1401 }
mpagenko38662d02021-08-11 09:45:19 +00001402 } else {
1403 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001404 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001405 }
1406 return
1407 }
1408 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001409 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001410}
1411
1412//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001413func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1414 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001415 var err error
1416 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1417 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1418 // 2.) activation of the inactive image
1419
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001421 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001422 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1423 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001424 }
1425 dh.lockUpgradeFsm.RLock()
1426 if dh.pOnuUpradeFsm != nil {
1427 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001428 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001429 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001430 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1431 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001432 }
mpagenko59862f02021-10-11 08:53:18 +00001433 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1434 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1435 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1436 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001437 // use the OnuVendor identification from this device for the internal unique name
1438 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001439 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001440 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001441 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001442 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001443 "device-id": dh.DeviceID, "error": err})
1444 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001445 }
mpagenko183647c2021-06-08 15:25:04 +00001446 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001448 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001449 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001450 } //else
1451 dh.lockUpgradeFsm.RUnlock()
1452
1453 // 2.) check if requested image-version equals the inactive one and start its activation
1454 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1455 var inactiveImageID uint16
1456 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1457 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001458 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1459 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001460 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001461 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001462 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001463 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 if err == nil {
1465 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1466 inactiveImageID, aCommitRequest); err != nil {
1467 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468 "device-id": dh.DeviceID, "error": err})
1469 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001470 }
1471 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001472 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001473 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001474 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001475 } //else
1476 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001477 "device-id": dh.DeviceID, "error": err})
1478 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001479}
1480
1481//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001482func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1483 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001484 var err error
1485 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1486 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1487 // 2.) commitment of the active image
1488
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001489 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001490 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1492 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001493 }
1494 dh.lockUpgradeFsm.RLock()
1495 if dh.pOnuUpradeFsm != nil {
1496 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001497 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001498 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001499 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1500 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001501 }
mpagenko59862f02021-10-11 08:53:18 +00001502 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1503 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1504 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1505 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001506 // use the OnuVendor identification from this device for the internal unique name
1507 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001508 // 1.) check a started upgrade process and relay the commitment request to it
1509 // the running upgrade may be based either on the imageIdentifier (started from download)
1510 // or on the imageVersion (started from pure activation)
1511 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1512 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001513 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001514 "device-id": dh.DeviceID, "error": err})
1515 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001516 }
mpagenko183647c2021-06-08 15:25:04 +00001517 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001519 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001520 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001521 } //else
1522 dh.lockUpgradeFsm.RUnlock()
1523
mpagenko183647c2021-06-08 15:25:04 +00001524 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001525 var activeImageID uint16
1526 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1527 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1529 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001530 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001531 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001533 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001534 if err == nil {
1535 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1536 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 "device-id": dh.DeviceID, "error": err})
1538 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001539 }
1540 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001541 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001542 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001543 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001544 } //else
1545 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001546 "device-id": dh.DeviceID, "error": err})
1547 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001548}
1549
mpagenkoaa3afe92021-05-21 16:20:58 +00001550func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001551 aVersion string) *voltha.ImageState {
1552 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001553 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001554 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001555 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001556 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1557 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1558 if aVersion == dh.pLastUpgradeImageState.Version {
1559 pImageState = dh.pLastUpgradeImageState
1560 } else { //state request for an image version different from last processed image version
1561 pImageState = &voltha.ImageState{
1562 Version: aVersion,
1563 //we cannot state something concerning this version
1564 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1565 Reason: voltha.ImageState_NO_ERROR,
1566 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1567 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001568 }
1569 }
mpagenko38662d02021-08-11 09:45:19 +00001570 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001571}
1572
1573func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1574 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001576 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001577 dh.lockUpgradeFsm.RLock()
1578 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001579 dh.lockUpgradeFsm.RUnlock()
1580 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001581 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001582 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1583 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1584 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1585 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1586 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1587 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001588 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1589 dh.upgradeCanceled = true
1590 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1591 }
mpagenko45586762021-10-01 08:30:22 +00001592 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001593 } else {
mpagenko45586762021-10-01 08:30:22 +00001594 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001595 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1596 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1597 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1598 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1599 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1600 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001601 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1602 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001603 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1604 //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 +00001605 }
1606}
1607
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001608func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1609
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001610 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001612 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001613 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001614 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1615 pDevEntry.MutexOnuImageStatus.Lock()
1616 pDevEntry.POnuImageStatus = onuImageStatus
1617 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001618
1619 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001620 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001621 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1622 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1624 pDevEntry.MutexOnuImageStatus.Lock()
1625 pDevEntry.POnuImageStatus = nil
1626 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001627 return images, err
1628}
1629
Himani Chawla6d2ae152020-09-02 13:11:20 +05301630// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001631// #####################################################################################
1632
1633// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301634// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001637 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1638 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639}
1640
1641// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001643
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001644 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001645 var err error
1646
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001647 // populate what we know. rest comes later after mib sync
1648 dh.device.Root = false
1649 dh.device.Vendor = "OpenONU"
1650 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001652 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001654 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001655
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001656 if !dh.IsReconciling() {
1657 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001658 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1659 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1660 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301661 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001662 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001664 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001665 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001666
Himani Chawla4d908332020-08-31 12:30:20 +05301667 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001668 dh.ponPortNumber = dh.device.ParentPortNo
1669
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001670 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1671 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1672 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001674 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301675 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676
1677 /*
1678 self._pon = PonPort.create(self, self._pon_port_number)
1679 self._pon.add_peer(self.parent_id, self._pon_port_number)
1680 self.logger.debug('adding-pon-port-to-agent',
1681 type=self._pon.get_port().type,
1682 admin_state=self._pon.get_port().admin_state,
1683 oper_status=self._pon.get_port().oper_status,
1684 )
1685 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001686 if !dh.IsReconciling() {
1687 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001688 var ponPortNo uint32 = 1
1689 if dh.ponPortNumber != 0 {
1690 ponPortNo = dh.ponPortNumber
1691 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001692
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001693 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001694 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001695 PortNo: ponPortNo,
1696 Label: fmt.Sprintf("pon-%d", ponPortNo),
1697 Type: voltha.Port_PON_ONU,
1698 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301699 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001700 PortNo: ponPortNo}}, // Peer port is parent's port number
1701 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001702 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001703 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001704 e.Cancel(err)
1705 return
1706 }
1707 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001709 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001710 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711}
1712
1713// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001715
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001716 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001717 var err error
1718 /*
1719 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1720 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1721 return nil
1722 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001724 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001725 e.Cancel(err)
1726 return
1727 }
1728
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001729 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001731 // reconcilement will be continued after mib download is done
1732 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001733
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001734 /*
1735 ############################################################################
1736 # Setup Alarm handler
1737 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1738 device.serial_number)
1739 ############################################################################
1740 # Setup PM configuration for this device
1741 # Pass in ONU specific options
1742 kwargs = {
1743 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1744 'heartbeat': self.heartbeat,
1745 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1746 }
1747 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1748 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1749 self.logical_device_id, device.serial_number,
1750 grouped=True, freq_override=False, **kwargs)
1751 pm_config = self._pm_metrics.make_proto()
1752 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1753 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1754 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1755
1756 # Note, ONU ID and UNI intf set in add_uni_port method
1757 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1758 ani_ports=[self._pon])
1759
1760 # Code to Run OMCI Test Action
1761 kwargs_omci_test_action = {
1762 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1763 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1764 }
1765 serial_number = device.serial_number
1766 self._test_request = OmciTestRequest(self.core_proxy,
1767 self.omci_agent, self.device_id,
1768 AniG, serial_number,
1769 self.logical_device_id,
1770 exclusive=False,
1771 **kwargs_omci_test_action)
1772
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001773 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001774 else:
1775 self.logger.info('onu-already-activated')
1776 */
Girish Gowdrae09a6202021-01-12 18:10:59 -0800