blob: 5910f5ff49a42df81195246890f60c0d0ce88e65 [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 Hildebrandt2b107642022-12-09 07:56:23 +000058 "google.golang.org/grpc/codes"
59 "google.golang.org/grpc/status"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060)
61
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000062const (
mpagenko101ac942021-11-16 15:01:29 +000063 //constants for reconcile flow check channel
64 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
65 cWaitReconcileFlowAbortOnError = 0xFFFE
66 cWaitReconcileFlowNoActivity = 0xFFFF
67)
68
69const (
70 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000071 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000072)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000073
mpagenko1cc3cb42020-07-27 15:24:38 +000074const (
mpagenko44bd8362021-11-15 11:40:05 +000075 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
76 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
77 // as long as such is not available by the libraries - use this workaround
78 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
79)
80
81const (
mpagenko1cc3cb42020-07-27 15:24:38 +000082 // events of Device FSM
83 devEvDeviceInit = "devEvDeviceInit"
84 devEvGrpcConnected = "devEvGrpcConnected"
85 devEvGrpcDisconnected = "devEvGrpcDisconnected"
86 devEvDeviceUpInd = "devEvDeviceUpInd"
87 devEvDeviceDownInd = "devEvDeviceDownInd"
88)
89const (
90 // states of Device FSM
91 devStNull = "devStNull"
92 devStDown = "devStDown"
93 devStInit = "devStInit"
94 devStConnected = "devStConnected"
95 devStUp = "devStUp"
96)
97
Holger Hildebrandt24d51952020-05-04 14:03:42 +000098//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
99const (
Himani Chawla4d908332020-08-31 12:30:20 +0530100 pon = voltha.EventSubCategory_PON
101 //olt = voltha.EventSubCategory_OLT
102 //ont = voltha.EventSubCategory_ONT
103 //onu = voltha.EventSubCategory_ONU
104 //nni = voltha.EventSubCategory_NNI
105 //service = voltha.EventCategory_SERVICE
106 //security = voltha.EventCategory_SECURITY
107 equipment = voltha.EventCategory_EQUIPMENT
108 //processing = voltha.EventCategory_PROCESSING
109 //environment = voltha.EventCategory_ENVIRONMENT
110 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000111)
112
113const (
114 cEventObjectType = "ONU"
115)
116const (
117 cOnuActivatedEvent = "ONU_ACTIVATED"
118)
119
mpagenkof1fc3862021-02-16 10:09:52 +0000120type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000122 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
126 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
127 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
128 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
129 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
130 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
131 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
132 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
133 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000134}
135
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000136const (
137 cNoReconciling = iota
138 cOnuConfigReconciling
139 cSkipOnuConfigReconciling
140)
141
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142// FlowCb is the flow control block containing flow add/delete information along with a response channel
143type FlowCb struct {
144 ctx context.Context // Flow handler context
145 addFlow bool // if true flow to be added, else removed
146 flowItem *of.OfpFlowStats
147 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400148 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700149 respChan *chan error // channel to report the Flow handling error
150}
151
Himani Chawla6d2ae152020-09-02 13:11:20 +0530152//deviceHandler will interact with the ONU ? device.
153type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000154 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155 DeviceType string
156 adminState string
157 device *voltha.Device
158 logicalDeviceID string
159 ProxyAddressID string
160 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530161 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000162 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163
khenaidoo7d3c5582021-08-11 18:09:44 -0400164 coreClient *vgrpc.Client
165 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000166
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800167 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400168 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800169
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170 pOpenOnuAc *OpenONUAC
171 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530172 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000173 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000174 pOnuOmciDevice *mib.OnuDeviceEntry
175 pOnuTP *avcfg.OnuUniTechProf
176 pOnuMetricsMgr *pmmgr.OnuMetricsManager
177 pAlarmMgr *almgr.OnuAlarmManager
178 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000179 exitChannel chan int
180 lockDevice sync.RWMutex
181 pOnuIndication *oop.OnuIndication
182 deviceReason uint8
183 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000184 pLockStateFsm *uniprt.LockStateFsm
185 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000186
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187 //flowMgr *OpenOltFlowMgr
188 //eventMgr *OpenOltEventMgr
189 //resourceMgr *rsrcMgr.OpenOltResourceMgr
190
191 //discOnus sync.Map
192 //onus sync.Map
193 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000194 collectorIsRunning bool
195 mutexCollectorFlag sync.RWMutex
196 stopCollector chan bool
197 alarmManagerIsRunning bool
198 mutextAlarmManagerFlag sync.RWMutex
199 stopAlarmManager chan bool
200 stopHeartbeatCheck chan bool
201 uniEntityMap cmn.OnuUniPortMap
202 mutexKvStoreContext sync.Mutex
203 lockVlanConfig sync.RWMutex
204 lockVlanAdd sync.RWMutex
205 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
206 lockUpgradeFsm sync.RWMutex
207 pOnuUpradeFsm *swupg.OnuUpgradeFsm
208 upgradeCanceled bool
209 reconciling uint8
210 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000211 reconcilingFirstPass bool
212 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000213 reconcilingReasonUpdate bool
214 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000215 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
216 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
217 reconcileExpiryComplete time.Duration
218 reconcileExpiryVlanConfig time.Duration
219 mutexReadyForOmciConfig sync.RWMutex
220 readyForOmciConfig bool
221 deletionInProgress bool
222 mutexDeletionInProgressFlag sync.RWMutex
223 pLastUpgradeImageState *voltha.ImageState
224 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700225
226 flowCbChan []chan FlowCb
227 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300228 mutexForDisableDeviceRequested sync.RWMutex
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000229 mutexOltAvailable sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700230 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
231 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300232 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000233 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000234}
235
Himani Chawla6d2ae152020-09-02 13:11:20 +0530236//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400237func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530238 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400239 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400241 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000243 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 dh.DeviceType = cloned.Type
245 dh.adminState = "up"
246 dh.device = cloned
247 dh.pOpenOnuAc = adapter
248 dh.exitChannel = make(chan int, 1)
249 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000250 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000251 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530253 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530254 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopHeartbeatCheck = make(chan bool, 2)
256 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000258 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000259 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000260 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000261 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300262 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000263 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000264 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000265 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000266 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300267 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000268 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000269 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000270 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
271 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
272 if rECSeconds < 2 {
273 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
274 rECSeconds = 2
275 }
276 rEVCSeconds := rECSeconds / 2
277 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000278 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000279 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000280 dh.pLastUpgradeImageState = &voltha.ImageState{
281 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
282 Reason: voltha.ImageState_UNKNOWN_ERROR,
283 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
284 }
285 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800287 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
288 dh.pmConfigs = cloned.PmConfigs
289 } /* else {
290 // will be populated when onu_metrics_mananger is initialized.
291 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800292
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 // Device related state machine
294 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000295 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000297 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
298 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
299 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
300 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
301 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 },
303 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000304 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
305 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
306 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
307 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
308 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
309 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
310 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
311 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312 },
313 )
mpagenkoaf801632020-07-03 10:00:42 +0000314
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 return &dh
316}
317
Himani Chawla6d2ae152020-09-02 13:11:20 +0530318// start save the device to the data model
319func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000320 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000322 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323}
324
Himani Chawla4d908332020-08-31 12:30:20 +0530325/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 logger.Debug("stopping-device-handler")
329 dh.exitChannel <- 1
330}
Himani Chawla4d908332020-08-31 12:30:20 +0530331*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332
333// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530334// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000335
Girish Gowdrae0140f02021-02-02 16:55:09 -0800336//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530337func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400338 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000340 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000341 if dh.pDeviceStateFsm.Is(devStNull) {
342 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000343 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 +0000344 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000345 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800346 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
347 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800348 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400349 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000350 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800351 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800352 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000353 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000355 }
356
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000357}
358
khenaidoo42dcdfd2021-10-19 17:34:12 -0400359func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000360 /* 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 +0530361 //assuming omci message content is hex coded!
362 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000365 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000366 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000368 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000370 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000371 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
372 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
375 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530376}
377
khenaidoo42dcdfd2021-10-19 17:34:12 -0400378func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000380
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000381 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000383 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
384 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 if dh.pOnuTP == nil {
387 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000389 log.Fields{"device-id": dh.DeviceID})
390 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 if !dh.IsReadyForOmciConfig() {
393 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
394 "device-state": dh.GetDeviceReasonString()})
395 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000397 //previous state test here was just this one, now extended for more states to reject the SetRequest:
398 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
399 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530400
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
403 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000404 dh.pOnuTP.LockTpProcMutex()
405 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406
mpagenko44bd8362021-11-15 11:40:05 +0000407 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000409 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410 }
411 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000412 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800413 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000414 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
415 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800416 return err
417 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000418 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
419 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000420
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000421 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530422
Girish Gowdra50e56422021-06-01 16:46:04 -0700423 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400424 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000425 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
426 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000427
428 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
429 if err != nil {
430 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
431 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
432 // stopping all further processing
433 _ = dh.UpdateInterface(ctx)
434 return err
435 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700436 // if there has been some change for some uni TechProfilePath
437 //in order to allow concurrent calls to other dh instances we do not wait for execution here
438 //but doing so we can not indicate problems to the caller (who does what with that then?)
439 //by now we just assume straightforward successful execution
440 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
441 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530442
Girish Gowdra50e56422021-06-01 16:46:04 -0700443 // deadline context to ensure completion of background routines waited for
444 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
445 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
446 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000447
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000448 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700449
450 var wg sync.WaitGroup
451 wg.Add(1) // for the 1 go routine to finish
452 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000453 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700454 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
456 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 -0700457 return tpErr
458 }
459 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
460 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000461 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700462 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700464 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000465 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
466 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 -0700467 return kvErr
468 }
469 return nil
470 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000471 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700472 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700473 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000475 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000476 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
477 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530478 return nil
479}
480
khenaidoo42dcdfd2021-10-19 17:34:12 -0400481func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000482 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530483
484 if dh.pOnuTP == nil {
485 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000486 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000487 log.Fields{"device-id": dh.DeviceID})
488 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000491 dh.pOnuTP.LockTpProcMutex()
492 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530493
mpagenko0f543222021-11-03 16:24:14 +0000494 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
495 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
496 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499 }
500 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000501 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800502 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000503 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
504 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 return err
506 }
mpagenko0f543222021-11-03 16:24:14 +0000507 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
508 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000509 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000510
Mahir Gunyel9545be22021-07-04 15:53:16 -0700511 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513
Himani Chawla26e555c2020-08-31 12:30:20 +0530514}
515
khenaidoo42dcdfd2021-10-19 17:34:12 -0400516func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000517 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 +0000518
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000519 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
522 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 if dh.pOnuTP == nil {
525 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 log.Fields{"device-id": dh.DeviceID})
528 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 }
530
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 dh.pOnuTP.LockTpProcMutex()
533 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000534
mpagenko0f543222021-11-03 16:24:14 +0000535 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
536 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
537 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000538 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000540 }
541 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700542 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000543 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800544 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000545 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
546 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800547 return err
548 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530550
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000551 var wg sync.WaitGroup
552 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
553 dctx, cancel := context.WithDeadline(context.Background(), deadline)
554 wg.Add(1)
555 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
556 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
557 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
558 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
559 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
560 return err
561 }
562
Mahir Gunyel9545be22021-07-04 15:53:16 -0700563 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000565
Mahir Gunyel9545be22021-07-04 15:53:16 -0700566}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000567
Mahir Gunyel9545be22021-07-04 15:53:16 -0700568func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
570 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700571 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
573 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530574 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700577 resourceName = "Gem"
578 } else {
579 resourceName = "Tcont"
580 }
581
582 // deadline context to ensure completion of background routines waited for
583 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
584 dctx, cancel := context.WithDeadline(context.Background(), deadline)
585
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000586 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700587
588 var wg sync.WaitGroup
589 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700591 resource, entryID, &wg)
592 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
594 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700595 return err
596 }
597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
599 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
600 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
601 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700602 var wg2 sync.WaitGroup
603 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
604 wg2.Add(1)
605 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000606 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 +0000607 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700608 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000609 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
610 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700611 return err
612 }
613 }
614 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000615 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700616 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530617 return nil
618}
619
mpagenkodff5dda2020-08-28 11:52:01 +0000620//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400622 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400623 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700624 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
625 var errorsList []error
626 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000627 //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 +0000628 if apOfFlowChanges.ToRemove != nil {
629 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000630 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000632 "device-id": dh.DeviceID})
633 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700634 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000635 continue
636 }
637 flowInPort := flow.GetInPort(flowItem)
638 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000639 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
640 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700641 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000642 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000643 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000644 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000645 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000647 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000648 continue
649 } else {
650 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000651 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000652 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
653 loUniPort = uniPort
654 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000657 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000658 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700659 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000660 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000661 }
662 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
665 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700666
667 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
668 // Step1 : Fill flowControlBlock
669 // Step2 : Push the flowControlBlock to ONU channel
670 // Step3 : Wait on response channel for response
671 // Step4 : Return error value
672 startTime := time.Now()
673 respChan := make(chan error)
674 flowCb := FlowCb{
675 ctx: ctx,
676 addFlow: false,
677 flowItem: flowItem,
678 flowMetaData: nil,
679 uniPort: loUniPort,
680 respChan: &respChan,
681 }
682 dh.flowCbChan[loUniPort.UniID] <- flowCb
683 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
684 // Wait on the channel for flow handlers return value
685 retError = <-respChan
686 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
687 if retError != nil {
688 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
689 log.Fields{"device-id": dh.DeviceID, "error": retError})
690 errorsList = append(errorsList, retError)
691 continue
692 }
693 } else {
694 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
695 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000696 }
697 }
698 }
699 }
mpagenko01e726e2020-10-23 09:45:29 +0000700 if apOfFlowChanges.ToAdd != nil {
701 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
702 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000704 "device-id": dh.DeviceID})
705 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700706 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000707 continue
708 }
709 flowInPort := flow.GetInPort(flowItem)
710 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000711 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
712 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700713 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000714 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000715 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000716 } else if flowInPort == dh.ponPortNumber {
717 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000719 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000720 continue
721 } else {
722 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000723 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000724 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
725 loUniPort = uniPort
726 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000728 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000729 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000730 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700731 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000732 continue
mpagenko01e726e2020-10-23 09:45:29 +0000733 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000734 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
735 // if not, we just throw some error here to have an indication about that, if we really need to support that
736 // then we would need to create some means to activate the internal stored flows
737 // after the device gets active automatically (and still with its dependency to the TechProfile)
738 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
739 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000740 if !dh.IsReadyForOmciConfig() {
741 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
742 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700743 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
744 errorsList = append(errorsList, retError)
745 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000746 }
747
mpagenko01e726e2020-10-23 09:45:29 +0000748 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000749 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000750 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
751 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700752 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
753 // Step1 : Fill flowControlBlock
754 // Step2 : Push the flowControlBlock to ONU channel
755 // Step3 : Wait on response channel for response
756 // Step4 : Return error value
757 startTime := time.Now()
758 respChan := make(chan error)
759 flowCb := FlowCb{
760 ctx: ctx,
761 addFlow: true,
762 flowItem: flowItem,
763 flowMetaData: apFlowMetaData,
764 uniPort: loUniPort,
765 respChan: &respChan,
766 }
767 dh.flowCbChan[loUniPort.UniID] <- flowCb
768 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
769 // Wait on the channel for flow handlers return value
770 retError = <-respChan
771 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
772 if retError != nil {
773 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
774 log.Fields{"device-id": dh.DeviceID, "error": retError})
775 errorsList = append(errorsList, retError)
776 continue
777 }
778 } else {
779 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
780 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000781 }
782 }
783 }
784 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700785 if len(errorsList) > 0 {
786 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
787 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
788 }
789 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000790}
791
Himani Chawla6d2ae152020-09-02 13:11:20 +0530792//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000793//following are the expected device states after this activity:
794//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
795// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
797 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300798 dh.mutexForDisableDeviceRequested.Lock()
799 dh.disableDeviceRequested = true
800 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000801 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000802 //note that disableDevice sequences in some 'ONU active' state may yield also
803 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000804 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000805 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000806 //disable-device shall be just a UNi/ONU-G related admin state setting
807 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000808
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000809 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000810 // disable UNI ports/ONU
811 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
812 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000813 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000814 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000817 }
818 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000819 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000821 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400822 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000824 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400825 OperStatus: voltha.OperStatus_UNKNOWN,
826 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000827 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000829 }
mpagenko01e726e2020-10-23 09:45:29 +0000830 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000831
832 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000833 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000834 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300835 }
836}
837
Himani Chawla6d2ae152020-09-02 13:11:20 +0530838//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
840 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000841
mpagenkoaa3afe92021-05-21 16:20:58 +0000842 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000843 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
844 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
845 // for real ONU's that should have nearly no influence
846 // Note that for real ONU's there is anyway a problematic situation with following sequence:
847 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
848 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
849 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000850 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000851
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000852 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000853 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300854 dh.mutexForDisableDeviceRequested.Lock()
855 dh.disableDeviceRequested = false
856 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000857 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000859 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000860 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000862 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300863}
864
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000867
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000869 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000870 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 return
872 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000874 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000875 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000876 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000878 }
mpagenko101ac942021-11-16 15:01:29 +0000879 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000880 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000881 }
Himani Chawla4d908332020-08-31 12:30:20 +0530882 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 pDevEntry.MutexPersOnuConfig.RLock()
884 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
885 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
886 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
887 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
888 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000890}
891
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000892func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000894
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000895 continueWithFlowConfig := false
896
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000897 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000898 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000899 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000900 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
901 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000902 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 dh.pOnuTP.LockTpProcMutex()
904 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000905
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000907 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000908 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
909 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000912 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
913 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000914 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000915 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700916 techProfsFound := false
917 techProfInstLoadFailed := false
918outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000919 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000920 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000921 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000922 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000923 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000924 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000925 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000926 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000927 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
928 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000929 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000931 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000933 var iaTechTpInst ia.TechProfileDownloadMessage
934 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800935 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000936 pDevEntry.MutexReconciledTpInstances.RLock()
937 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
938 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000939 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000940 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700941 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000942 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700943 break outerLoop
944 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000945 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000946 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700947 var tpInst tech_profile.TechProfileInstance
948 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400949 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700950 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000951 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700953 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000954 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700956 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
957 break outerLoop
958 }
959
Girish Gowdra041dcb32020-11-16 16:54:30 -0800960 // deadline context to ensure completion of background routines waited for
961 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
962 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000964
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800966 var wg sync.WaitGroup
967 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000968 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000970 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
971 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700972 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
973 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800974 }
mpagenko2dc896e2021-08-02 12:03:59 +0000975 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000976 if len(uniData.PersFlowParams) != 0 {
977 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000978 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000980 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000981 } // for all UNI entries from SOnuPersistentData
982 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
983 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000984 }
mpagenko2dc896e2021-08-02 12:03:59 +0000985
986 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
987 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000988
989 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000990}
991
992func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
993 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
994 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000995 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000996 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000997 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000998 return
999 }
mpagenko2dc896e2021-08-02 12:03:59 +00001000 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001001 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001002 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001003 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001004 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001005 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001006 }
mpagenko2dc896e2021-08-02 12:03:59 +00001007 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001008 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001009 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001010 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001011 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012}
1013
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1015 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001016
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001018 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001019 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001020 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001021 return
1022 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001024 pDevEntry.MutexPersOnuConfig.RLock()
1025 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1026 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001029 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001030 return
1031 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001032 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001033 var uniVlanConfigEntries []uint8
1034 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1035
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001037 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1038 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001039 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001041 continue
1042 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001043 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001044 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001045 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001046 // It doesn't make sense to configure any flows if no TPs are available
1047 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001048 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1050 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001051 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001053
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001055 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001056 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001057 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001058 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1059 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001060 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001061 return
1062 }
mpagenko101ac942021-11-16 15:01:29 +00001063 //needed to split up function due to sca complexity
1064 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1065
mpagenko2dc896e2021-08-02 12:03:59 +00001066 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001067 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001068 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1069 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001070 // this can't be used as global finished reconciling flag because
1071 // assumes is getting called before the state machines for the last flow is completed,
1072 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1074 } // for all UNI entries from SOnuPersistentData
1075 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001076
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001077 if !flowsFound {
1078 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001080 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001081 return
1082 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001083 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1084 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1085 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1086 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1087 log.Fields{"device-id": dh.DeviceID})
1088 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1089 if pDevEntry != nil {
1090 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001091 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001092 } else {
1093 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1094 log.Fields{"device-id": dh.DeviceID})
1095 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1096 if pDevEntry != nil {
1097 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1098 }
1099 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001100 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001101 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001102}
1103
mpagenko101ac942021-11-16 15:01:29 +00001104func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1105 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1106 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1107 flowsProcessed := 0
1108 lastFlowToReconcile := false
1109 loUniID := apUniPort.UniID
1110 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001111 if !(*apFlowsFound) {
1112 *apFlowsFound = true
1113 syncChannel := make(chan struct{})
1114 // start go routine with select() on reconciling vlan config channel before
1115 // starting vlan config reconciling process to prevent loss of any signal
1116 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1117 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1118 //block until the wait routine is really blocked on channel input
1119 // in order to prevent to early ready signal from VlanConfig processing
1120 <-syncChannel
1121 }
1122 if flowsProcessed == len(aPersFlowParam)-1 {
1123 var uniAdded bool
1124 lastFlowToReconcile = true
1125 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1126 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001127 }
1128 }
mpagenko101ac942021-11-16 15:01:29 +00001129 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1130 "device-id": dh.DeviceID, "uni-id": loUniID,
1131 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1132 dh.lockVlanConfig.Lock()
1133 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1134 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1135 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301136 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 +00001137 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1138 }
1139 } else {
1140 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301141 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301142 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001143 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1144 }
1145 }
1146 dh.lockVlanConfig.Unlock()
1147 flowsProcessed++
1148 } //for all flows of this UNI
1149}
1150
1151//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1152// and decrements the according handler wait group waiting for these indications
1153func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1154 waitGroup *cmn.WaitGroupWithTimeOut) {
1155 var reconciledUniVlanConfigEntries []uint8
1156 var appended bool
1157 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1158 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1159 "device-id": dh.DeviceID, "expiry": expiry})
1160 // indicate blocking on channel now to the caller
1161 aSyncChannel <- struct{}{}
1162 for {
1163 select {
1164 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1165 switch uniIndication {
1166 // no activity requested (should normally not be received) - just continue waiting
1167 case cWaitReconcileFlowNoActivity:
1168 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1169 case cWaitReconcileFlowAbortOnError:
1170 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1171 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1172 return
1173 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1174 case cWaitReconcileFlowAbortOnSuccess:
1175 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1176 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1177 return
1178 // this should be a valid UNI vlan config done indication
1179 default:
1180 if uniIndication < platform.MaxUnisPerOnu {
1181 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1182 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1183 if reconciledUniVlanConfigEntries, appended =
1184 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1185 waitGroup.Done()
1186 }
1187 } else {
1188 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1189 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1190 }
1191 } //switch uniIndication
1192
1193 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1194 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1195 log.Fields{"device-id": dh.DeviceID})
1196 return
1197 }
1198 }
1199}
1200
1201func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1202 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1203}
1204
1205func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1206 for _, ele := range slice {
1207 if ele == val {
1208 return slice, false
1209 }
1210 }
1211 return append(slice, val), true
1212}
1213
1214// sendChReconcileFinished - sends true or false on reconcileFinish channel
1215func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1216 if dh != nil { //if the object still exists (might have been already deleted in background)
1217 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1218 select {
1219 case dh.chReconcilingFinished <- success:
1220 default:
1221 }
1222 }
1223}
1224
1225// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1226func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1227 if dh != nil { //if the object still exists (might have been already deleted in background)
1228 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1229 select {
1230 case dh.chUniVlanConfigReconcilingDone <- value:
1231 default:
1232 }
1233 }
1234}
1235
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001238
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001240 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001241 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001242 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001243 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001244 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001245
1246 // deadline context to ensure completion of background routines waited for
1247 //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 +05301248 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001249 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001250
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001251 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001252
1253 var wg sync.WaitGroup
1254 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001255 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001257
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001258 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001260}
1261
mpagenko15ff4a52021-03-02 10:09:20 +00001262//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1263// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001264// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001265//was and is called in background - error return does not make sense
1266func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001268 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001270 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001271 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301273 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001275 return
Himani Chawla4d908332020-08-31 12:30:20 +05301276 }
mpagenko01e726e2020-10-23 09:45:29 +00001277
1278 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001280
mpagenko44bd8362021-11-15 11:40:05 +00001281 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001283 // 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 -04001284 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001286 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001287 OperStatus: voltha.OperStatus_DISCOVERED,
1288 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001289 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001291 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001292 }
mpagenkoe4782082021-11-25 12:04:26 +00001293 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001294 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001295 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001297 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1298 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1299 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1300 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001301}
1302
mpagenkoc8bba412021-01-15 15:38:44 +00001303//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001304// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001305func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001306 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001307 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001309
1310 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001311 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001312 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1314 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001315 }
1316
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001318 var inactiveImageID uint16
1319 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1320 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001321 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1322 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001323 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001325 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001326 if err == nil {
1327 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1328 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001329 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001330 }
1331 } else {
1332 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001334 }
mpagenko15ff4a52021-03-02 10:09:20 +00001335 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001336 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001338 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1339 dh.upgradeCanceled = true
1340 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1341 }
mpagenko38662d02021-08-11 09:45:19 +00001342 //no effort spent anymore for the old API to automatically cancel and restart the download
1343 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001344 }
mpagenko15ff4a52021-03-02 10:09:20 +00001345 } else {
1346 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001348 }
1349 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1351 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001352 }
1353 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001354}
1355
mpagenkoc26d4c02021-05-06 14:27:57 +00001356//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1357// after the OnuImage has been downloaded to the adapter, called in background
1358func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001360
1361 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001362 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001363 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001365 return
1366 }
1367
1368 var inactiveImageID uint16
1369 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1370 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001372
mpagenko59862f02021-10-11 08:53:18 +00001373 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001374 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001375 // but must be still locked at calling createOnuUpgradeFsm
1376 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1377 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1378 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001379 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1380 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001382 //flush the remove upgradeFsmChan channel
1383 select {
1384 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001385 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001386 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001387 }
mpagenko59862f02021-10-11 08:53:18 +00001388 dh.lockUpgradeFsm.Unlock()
1389 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1390 dh.upgradeCanceled = true
1391 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1392 }
mpagenko38662d02021-08-11 09:45:19 +00001393 select {
1394 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001395 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001396 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1397 return
1398 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001399 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001400 }
mpagenko59862f02021-10-11 08:53:18 +00001401 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001402 }
mpagenko38662d02021-08-11 09:45:19 +00001403
1404 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001405 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001406 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001407 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001408 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001409 if err == nil {
1410 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1411 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1412 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001414 return
1415 }
mpagenko38662d02021-08-11 09:45:19 +00001416 } else {
1417 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001418 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001419 }
1420 return
1421 }
1422 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001424}
1425
1426//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001427func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1428 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001429 var err error
1430 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1431 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1432 // 2.) activation of the inactive image
1433
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001434 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001435 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001436 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1437 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001438 }
1439 dh.lockUpgradeFsm.RLock()
1440 if dh.pOnuUpradeFsm != nil {
1441 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001442 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001443 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001444 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1445 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001446 }
mpagenko59862f02021-10-11 08:53:18 +00001447 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1448 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1449 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1450 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 // use the OnuVendor identification from this device for the internal unique name
1452 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001453 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001454 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001455 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001456 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 "device-id": dh.DeviceID, "error": err})
1458 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001459 }
mpagenko183647c2021-06-08 15:25:04 +00001460 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001461 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001462 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001463 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 } //else
1465 dh.lockUpgradeFsm.RUnlock()
1466
1467 // 2.) check if requested image-version equals the inactive one and start its activation
1468 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1469 var inactiveImageID uint16
1470 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1471 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001472 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1473 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001474 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001475 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001476 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001477 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001478 if err == nil {
1479 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1480 inactiveImageID, aCommitRequest); err != nil {
1481 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001482 "device-id": dh.DeviceID, "error": err})
1483 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001484 }
1485 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001487 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001488 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001489 } //else
1490 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 "device-id": dh.DeviceID, "error": err})
1492 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001493}
1494
1495//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001496func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1497 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001498 var err error
1499 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1500 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1501 // 2.) commitment of the active image
1502
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001503 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001504 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001505 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1506 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001507 }
1508 dh.lockUpgradeFsm.RLock()
1509 if dh.pOnuUpradeFsm != nil {
1510 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001511 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001512 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001513 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1514 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001515 }
mpagenko59862f02021-10-11 08:53:18 +00001516 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1517 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1518 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1519 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001520 // use the OnuVendor identification from this device for the internal unique name
1521 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001522 // 1.) check a started upgrade process and relay the commitment request to it
1523 // the running upgrade may be based either on the imageIdentifier (started from download)
1524 // or on the imageVersion (started from pure activation)
1525 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1526 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001527 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 "device-id": dh.DeviceID, "error": err})
1529 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001530 }
mpagenko183647c2021-06-08 15:25:04 +00001531 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001533 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001534 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001535 } //else
1536 dh.lockUpgradeFsm.RUnlock()
1537
mpagenko183647c2021-06-08 15:25:04 +00001538 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001539 var activeImageID uint16
1540 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1541 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1543 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001544 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001545 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001546 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001547 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001548 if err == nil {
1549 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1550 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001551 "device-id": dh.DeviceID, "error": err})
1552 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001553 }
1554 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001555 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001556 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001557 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001558 } //else
1559 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001560 "device-id": dh.DeviceID, "error": err})
1561 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001562}
1563
mpagenkoaa3afe92021-05-21 16:20:58 +00001564func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001565 aVersion string) *voltha.ImageState {
1566 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001567 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001568 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001569 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001570 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1571 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1572 if aVersion == dh.pLastUpgradeImageState.Version {
1573 pImageState = dh.pLastUpgradeImageState
1574 } else { //state request for an image version different from last processed image version
1575 pImageState = &voltha.ImageState{
1576 Version: aVersion,
1577 //we cannot state something concerning this version
1578 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1579 Reason: voltha.ImageState_NO_ERROR,
1580 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1581 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001582 }
1583 }
mpagenko38662d02021-08-11 09:45:19 +00001584 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001585}
1586
1587func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1588 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001589 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001590 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001591 dh.lockUpgradeFsm.RLock()
1592 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001593 dh.lockUpgradeFsm.RUnlock()
1594 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001595 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001596 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1597 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1598 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1599 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1600 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1601 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001602 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1603 dh.upgradeCanceled = true
1604 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1605 }
mpagenko45586762021-10-01 08:30:22 +00001606 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001607 } else {
mpagenko45586762021-10-01 08:30:22 +00001608 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001609 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1610 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1611 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1612 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1613 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1614 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001615 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1616 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001617 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1618 //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 +00001619 }
1620}
1621
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001622func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1623
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001625
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001626 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001627 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1629 pDevEntry.MutexOnuImageStatus.Lock()
1630 pDevEntry.POnuImageStatus = onuImageStatus
1631 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001632
1633 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001634 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001635 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1636 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001637 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1638 pDevEntry.MutexOnuImageStatus.Lock()
1639 pDevEntry.POnuImageStatus = nil
1640 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001641 return images, err
1642}
1643
Himani Chawla6d2ae152020-09-02 13:11:20 +05301644// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001645// #####################################################################################
1646
1647// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301648// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001651 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1652 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653}
1654
1655// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001657
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001658 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001659 var err error
1660
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661 // populate what we know. rest comes later after mib sync
1662 dh.device.Root = false
1663 dh.device.Vendor = "OpenONU"
1664 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001666 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001668 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001669
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 if !dh.IsReconciling() {
1671 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001672 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1673 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1674 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301675 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001676 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001678 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001679 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001680
Himani Chawla4d908332020-08-31 12:30:20 +05301681 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001682 dh.ponPortNumber = dh.device.ParentPortNo
1683
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001684 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1685 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1686 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301689 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001690
1691 /*
1692 self._pon = PonPort.create(self, self._pon_port_number)
1693 self._pon.add_peer(self.parent_id, self._pon_port_number)
1694 self.logger.debug('adding-pon-port-to-agent',
1695 type=self._pon.get_port().type,
1696 admin_state=self._pon.get_port().admin_state,
1697 oper_status=self._pon.get_port().oper_status,
1698 )
1699 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001700 if !dh.IsReconciling() {
1701 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001702 var ponPortNo uint32 = 1
1703 if dh.ponPortNumber != 0 {
1704 ponPortNo = dh.ponPortNumber
1705 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001706
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001707 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001709 PortNo: ponPortNo,
1710 Label: fmt.Sprintf("pon-%d", ponPortNo),
1711 Type: voltha.Port_PON_ONU,
1712 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301713 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001714 PortNo: ponPortNo}}, // Peer port is parent's port number
1715 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001716 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001717 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001718 e.Cancel(err)
1719 return
1720 }
1721 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001722 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001724 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001725}
1726
1727// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001728func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001729
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001730 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001731 var err error
1732 /*
1733 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1734 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1735 return nil
1736 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001738 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001739 e.Cancel(err)
1740 return
1741 }
1742
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001743 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001745 // reconcilement will be continued after mib download is done
1746 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001747
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001748 /*
1749 ############################################################################
1750 # Setup Alarm handler
1751 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1752 device.serial_number)
1753 ############################################################################
1754 # Setup PM configuration for this device
1755 # Pass in ONU specific options
1756 kwargs = {
1757 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1758 'heartbeat': self.heartbeat,
1759 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1760 }
1761 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1762 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1763 self.logical_device_id, device.serial_number,
1764 grouped=True, freq_override=False, **kwargs)
1765 pm_config = self._pm_metrics.make_proto()
1766 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1767 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1768 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1769
1770 # Note, ONU ID and UNI intf set in add_uni_port method