blob: 929964c7849cb67e6aca7dd3861fc0cebde0a05d [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
28 "github.com/gogo/protobuf/proto"
29 "github.com/golang/protobuf/ptypes"
30 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000031 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
33 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053034 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000035 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
36 "github.com/opencord/voltha-lib-go/v4/pkg/log"
37 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050038 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
40 "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v4/go/openolt"
44 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
47/*
48// Constants for number of retries and for timeout
49const (
50 MaxRetry = 10
51 MaxTimeOutInMs = 500
52)
53*/
54
mpagenko1cc3cb42020-07-27 15:24:38 +000055const (
56 // events of Device FSM
57 devEvDeviceInit = "devEvDeviceInit"
58 devEvGrpcConnected = "devEvGrpcConnected"
59 devEvGrpcDisconnected = "devEvGrpcDisconnected"
60 devEvDeviceUpInd = "devEvDeviceUpInd"
61 devEvDeviceDownInd = "devEvDeviceDownInd"
62)
63const (
64 // states of Device FSM
65 devStNull = "devStNull"
66 devStDown = "devStDown"
67 devStInit = "devStInit"
68 devStConnected = "devStConnected"
69 devStUp = "devStUp"
70)
71
Holger Hildebrandt24d51952020-05-04 14:03:42 +000072//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
73const (
Himani Chawla4d908332020-08-31 12:30:20 +053074 pon = voltha.EventSubCategory_PON
75 //olt = voltha.EventSubCategory_OLT
76 //ont = voltha.EventSubCategory_ONT
77 //onu = voltha.EventSubCategory_ONU
78 //nni = voltha.EventSubCategory_NNI
79 //service = voltha.EventCategory_SERVICE
80 //security = voltha.EventCategory_SECURITY
81 equipment = voltha.EventCategory_EQUIPMENT
82 //processing = voltha.EventCategory_PROCESSING
83 //environment = voltha.EventCategory_ENVIRONMENT
84 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085)
86
87const (
88 cEventObjectType = "ONU"
89)
90const (
91 cOnuActivatedEvent = "ONU_ACTIVATED"
92)
93
Holger Hildebrandt10d98192021-01-27 15:29:31 +000094type usedOmciConfigFsms int
95
96const (
97 cUploadFsm usedOmciConfigFsms = iota
98 cDownloadFsm
99 cUniLockFsm
100 cUniUnLockFsm
101 cAniConfigFsm
102 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800103 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000104 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105)
106
mpagenkof1fc3862021-02-16 10:09:52 +0000107type omciIdleCheckStruct struct {
108 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
109 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000110}
111
mpagenkof1fc3862021-02-16 10:09:52 +0000112var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
113 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
114 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
115 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
117 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
118 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
119 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000120 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000123const (
124 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000125 drUnset = 0
126 drActivatingOnu = 1
127 drStartingOpenomci = 2
128 drDiscoveryMibsyncComplete = 3
129 drInitialMibDownloaded = 4
130 drTechProfileConfigDownloadSuccess = 5
131 drOmciFlowsPushed = 6
132 drOmciAdminLock = 7
133 drOnuReenabled = 8
134 drStoppingOpenomci = 9
135 drRebooting = 10
136 drOmciFlowsDeleted = 11
137 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000138)
139
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000140var deviceReasonMap = map[uint8]string{
141 drUnset: "unset",
142 drActivatingOnu: "activating-onu",
143 drStartingOpenomci: "starting-openomci",
144 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
145 drInitialMibDownloaded: "initial-mib-downloaded",
146 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
147 drOmciFlowsPushed: "omci-flows-pushed",
148 drOmciAdminLock: "omci-admin-lock",
149 drOnuReenabled: "onu-reenabled",
150 drStoppingOpenomci: "stopping-openomci",
151 drRebooting: "rebooting",
152 drOmciFlowsDeleted: "omci-flows-deleted",
153 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
154}
155
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000156const (
157 cNoReconciling = iota
158 cOnuConfigReconciling
159 cSkipOnuConfigReconciling
160)
161
Himani Chawla6d2ae152020-09-02 13:11:20 +0530162//deviceHandler will interact with the ONU ? device.
163type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000164 deviceID string
165 DeviceType string
166 adminState string
167 device *voltha.Device
168 logicalDeviceID string
169 ProxyAddressID string
170 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530171 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000172 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000174 coreProxy adapterif.CoreProxy
175 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530176 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000177
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800178 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800179
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180 pOpenOnuAc *OpenONUAC
181 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530182 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000183 deviceEntrySet chan bool //channel for DeviceEntry set event
184 pOnuOmciDevice *OnuDeviceEntry
185 pOnuTP *onuUniTechProf
186 pOnuMetricsMgr *onuMetricsManager
187 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700188 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000189 exitChannel chan int
190 lockDevice sync.RWMutex
191 pOnuIndication *oop.OnuIndication
192 deviceReason uint8
193 mutexDeviceReason sync.RWMutex
194 pLockStateFsm *lockStateFsm
195 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197 //flowMgr *OpenOltFlowMgr
198 //eventMgr *OpenOltEventMgr
199 //resourceMgr *rsrcMgr.OpenOltResourceMgr
200
201 //discOnus sync.Map
202 //onus sync.Map
203 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000204 collectorIsRunning bool
205 mutexCollectorFlag sync.RWMutex
206 stopCollector chan bool
207 alarmManagerIsRunning bool
208 mutextAlarmManagerFlag sync.RWMutex
209 stopAlarmManager chan bool
210 stopHeartbeatCheck chan bool
211 uniEntityMap map[uint32]*onuUniPort
212 mutexKvStoreContext sync.Mutex
213 lockVlanConfig sync.RWMutex
214 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
215 lockUpgradeFsm sync.RWMutex
216 pOnuUpradeFsm *OnuUpgradeFsm
217 reconciling uint8
218 mutexReconcilingFlag sync.RWMutex
219 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000220 reconcilingFlows bool
221 mutexReconcilingFlowsFlag sync.RWMutex
222 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000223 mutexReadyForOmciConfig sync.RWMutex
224 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000225 deletionInProgress bool
226 mutexDeletionInProgressFlag sync.RWMutex
mpagenkoaa3afe92021-05-21 16:20:58 +0000227 upgradeSuccess bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228}
229
Himani Chawla6d2ae152020-09-02 13:11:20 +0530230//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530231func newDeviceHandler(ctx context.Context, cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 dh.coreProxy = cp
234 dh.AdapterProxy = ap
235 dh.EventProxy = ep
236 cloned := (proto.Clone(device)).(*voltha.Device)
237 dh.deviceID = cloned.Id
238 dh.DeviceType = cloned.Type
239 dh.adminState = "up"
240 dh.device = cloned
241 dh.pOpenOnuAc = adapter
242 dh.exitChannel = make(chan int, 1)
243 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000244 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000245 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530247 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530248 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249 dh.stopHeartbeatCheck = make(chan bool, 2)
250 //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 +0000251 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530252 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000253 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000254 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000255 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000256 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000257 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000258 dh.reconcilingFlows = false
259 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000260 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000261 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000262
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800263 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
264 dh.pmConfigs = cloned.PmConfigs
265 } /* else {
266 // will be populated when onu_metrics_mananger is initialized.
267 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800268
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269 // Device related state machine
270 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000271 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000273 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
274 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
275 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
276 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
277 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278 },
279 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
281 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
282 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
283 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
284 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
285 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
286 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
287 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 },
289 )
mpagenkoaf801632020-07-03 10:00:42 +0000290
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291 return &dh
292}
293
Himani Chawla6d2ae152020-09-02 13:11:20 +0530294// start save the device to the data model
295func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000298 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299}
300
Himani Chawla4d908332020-08-31 12:30:20 +0530301/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530303func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304 logger.Debug("stopping-device-handler")
305 dh.exitChannel <- 1
306}
Himani Chawla4d908332020-08-31 12:30:20 +0530307*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308
309// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530310// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311
Girish Gowdrae0140f02021-02-02 16:55:09 -0800312//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530313func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000314 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000317 if dh.pDeviceStateFsm.Is(devStNull) {
318 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000319 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800322 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
323 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800324 // Now, set the initial PM configuration for that device
325 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
326 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
327 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800328 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000331 }
332
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000333}
334
mpagenko057889c2021-01-21 16:51:58 +0000335func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530336 msgBody := msg.GetBody()
337 omciMsg := &ic.InterAdapterOmciMessage{}
338 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 "device-id": dh.deviceID, "error": err})
341 return err
342 }
343
mpagenko80622a52021-02-09 16:53:23 +0000344 /* 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 +0530345 //assuming omci message content is hex coded!
346 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530348 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000349 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530351 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000352 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000354 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": omciMsg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530356 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000358 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530359}
360
Himani Chawla6d2ae152020-09-02 13:11:20 +0530361func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000362 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530363 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000364
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000366
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000370 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
371 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 if dh.pOnuTP == nil {
373 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000376 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530377 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000378 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000380 "device-state": dh.getDeviceReasonString()})
381 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530382 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000383 //previous state test here was just this one, now extended for more states to reject the SetRequest:
384 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
385 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530386
387 msgBody := msg.GetBody()
388 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
389 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 "device-id": dh.deviceID, "error": err})
392 return err
393 }
394
395 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
397 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000399 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400
401 if techProfMsg.UniId > 255 {
402 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
403 techProfMsg.UniId, dh.deviceID))
404 }
405 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800406 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
407 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000408 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800409 return err
410 }
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700411 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000412
dbainbri4d3a0dc2020-12-02 00:33:42 +0000413 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700414 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 // if there has been some change for some uni TechProfilePath
416 //in order to allow concurrent calls to other dh instances we do not wait for execution here
417 //but doing so we can not indicate problems to the caller (who does what with that then?)
418 //by now we just assume straightforward successful execution
419 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
420 // possible problems to the caller later autonomously
421
422 // deadline context to ensure completion of background routines waited for
423 //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 +0530424 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530425 dctx, cancel := context.WithDeadline(context.Background(), deadline)
426
Girish Gowdra041dcb32020-11-16 16:54:30 -0800427 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000428
Himani Chawla26e555c2020-08-31 12:30:20 +0530429 var wg sync.WaitGroup
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700430 wg.Add(1) // for the 1 go routine to finish
Himani Chawla26e555c2020-08-31 12:30:20 +0530431 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000432 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000433 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700434 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
435 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.Path})
436 return tpErr
437 }
438 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
439 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
440 pDevEntry.resetKvProcessingErrorIndication()
441 wg.Add(1) // for the 1 go routine to finish
442 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
443 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
444 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
445 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.Path})
446 return kvErr
447 }
448 return nil
Himani Chawla26e555c2020-08-31 12:30:20 +0530449 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450 // no change, nothing really to do - return success
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700451 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.Path, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 return nil
453}
454
Himani Chawla6d2ae152020-09-02 13:11:20 +0530455func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000456 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530457 msg *ic.InterAdapterMessage) error {
458
dbainbri4d3a0dc2020-12-02 00:33:42 +0000459 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000460
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000462 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000464 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
465 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530466 if dh.pOnuTP == nil {
467 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000468 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000470 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530471 }
472
473 msgBody := msg.GetBody()
474 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
475 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 "device-id": dh.deviceID, "error": err})
478 return err
479 }
480
481 //compare TECH_PROFILE_DOWNLOAD_REQUEST
482 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530484
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485 if delGemPortMsg.UniId > 255 {
486 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
487 delGemPortMsg.UniId, dh.deviceID))
488 }
489 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800490 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
491 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800493 return err
494 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530495
mpagenkofc4f56e2020-11-04 17:17:49 +0000496 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497
mpagenkofc4f56e2020-11-04 17:17:49 +0000498 // deadline context to ensure completion of background routines waited for
499 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
500 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000501
Girish Gowdra041dcb32020-11-16 16:54:30 -0800502 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503
mpagenkofc4f56e2020-11-04 17:17:49 +0000504 var wg sync.WaitGroup
505 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000507 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000508 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000509
Girish Gowdra041dcb32020-11-16 16:54:30 -0800510 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530511}
512
Himani Chawla6d2ae152020-09-02 13:11:20 +0530513func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000514 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
dbainbri4d3a0dc2020-12-02 00:33:42 +0000517 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000518
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000522 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
523 }
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",
Himani Chawla26e555c2020-08-31 12:30:20 +0530527 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 }
530
531 msgBody := msg.GetBody()
532 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
533 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530535 "device-id": dh.deviceID, "error": err})
536 return err
537 }
538
539 //compare TECH_PROFILE_DOWNLOAD_REQUEST
540 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000542
543 if delTcontMsg.UniId > 255 {
544 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
545 delTcontMsg.UniId, dh.deviceID))
546 }
547 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800548 tpPath := delTcontMsg.TpPath
549 tpID, err := GetTpIDFromTpPath(tpPath)
550 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000551 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800552 return err
553 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000554
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700556 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530557 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530558 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530559 dctx, cancel := context.WithDeadline(context.Background(), deadline)
560
Girish Gowdra041dcb32020-11-16 16:54:30 -0800561 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000562 pDevEntry.resetKvProcessingErrorIndication()
563
Himani Chawla26e555c2020-08-31 12:30:20 +0530564 var wg sync.WaitGroup
565 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000566 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530567 cResourceTcont, delTcontMsg.AllocId, &wg)
568 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000569 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
570 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000571
Girish Gowdra041dcb32020-11-16 16:54:30 -0800572 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530573 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530574 return nil
575}
576
Himani Chawla6d2ae152020-09-02 13:11:20 +0530577//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000578// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
579// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000581 msgID := msg.Header.Id
582 msgType := msg.Header.Type
583 fromTopic := msg.Header.FromTopic
584 toTopic := msg.Header.ToTopic
585 toDeviceID := msg.Header.ToDeviceId
586 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000588 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
589
590 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000591 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000592 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
593 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000594 {
mpagenko057889c2021-01-21 16:51:58 +0000595 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000596 }
mpagenkoaf801632020-07-03 10:00:42 +0000597 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
598 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000599 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000600 }
601 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
602 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000603 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000604
mpagenkoaf801632020-07-03 10:00:42 +0000605 }
606 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
607 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000608 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000609 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000610 default:
611 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000612 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000613 "msgType": msg.Header.Type, "device-id": dh.deviceID})
614 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000615 }
616 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000617}
618
mpagenkodff5dda2020-08-28 11:52:01 +0000619//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
621 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000622 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000624
mpagenko01e726e2020-10-23 09:45:29 +0000625 var retError error = nil
626 //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 +0000627 if apOfFlowChanges.ToRemove != nil {
628 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000629 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000631 "device-id": dh.deviceID})
632 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000633 continue
634 }
635 flowInPort := flow.GetInPort(flowItem)
636 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000638 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
639 continue
640 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000641 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000642 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000644 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000645 continue
646 } else {
647 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530648 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000649 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
650 loUniPort = uniPort
651 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000653 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
654 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
655 flowInPort, dh.deviceID)
656 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000657 }
658 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000660 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000661 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000663 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000664 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000665 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000666 log.Fields{"device-id": dh.deviceID, "error": err})
667 retError = err
668 continue
669 //return err
670 } else { // if last setting succeeds, overwrite possibly previously set error
671 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000672 }
673 }
674 }
675 }
mpagenko01e726e2020-10-23 09:45:29 +0000676 if apOfFlowChanges.ToAdd != nil {
677 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
678 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000680 "device-id": dh.deviceID})
681 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
682 continue
683 }
684 flowInPort := flow.GetInPort(flowItem)
685 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000687 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
688 continue
689 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
690 } else if flowInPort == dh.ponPortNumber {
691 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000692 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000693 "device-id": dh.deviceID, "inPort": flowInPort})
694 continue
695 } else {
696 // this is the relevant upstream flow
697 var loUniPort *onuUniPort
698 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
699 loUniPort = uniPort
700 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000702 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
703 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
704 flowInPort, dh.deviceID)
705 continue
706 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
707 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000708 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
709 // if not, we just throw some error here to have an indication about that, if we really need to support that
710 // then we would need to create some means to activate the internal stored flows
711 // after the device gets active automatically (and still with its dependency to the TechProfile)
712 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
713 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000714 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000716 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000717 return fmt.Errorf("improper device state on device %s", dh.deviceID)
718 }
719
mpagenko01e726e2020-10-23 09:45:29 +0000720 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000722 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
723 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000725 //try next flow after processing error
726 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000728 log.Fields{"device-id": dh.deviceID, "error": err})
729 retError = err
730 continue
731 //return err
732 } else { // if last setting succeeds, overwrite possibly previously set error
733 retError = nil
734 }
735 }
736 }
737 }
738 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000739}
740
Himani Chawla6d2ae152020-09-02 13:11:20 +0530741//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000742//following are the expected device states after this activity:
743//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
744// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
746 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000747
mpagenko900ee4b2020-10-12 11:56:34 +0000748 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000749 //note that disableDevice sequences in some 'ONU active' state may yield also
750 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000751 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000752 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000753 //disable-device shall be just a UNi/ONU-G related admin state setting
754 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000755
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000756 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000757 // disable UNI ports/ONU
758 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
759 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000761 } else { //LockStateFSM already init
762 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000764 }
765 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000767 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000769 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
770 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000772 }
mpagenko01e726e2020-10-23 09:45:29 +0000773 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000774
775 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000777 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300778 }
779}
780
Himani Chawla6d2ae152020-09-02 13:11:20 +0530781//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
783 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000784
mpagenkoaa3afe92021-05-21 16:20:58 +0000785 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000786 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
787 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
788 // for real ONU's that should have nearly no influence
789 // Note that for real ONU's there is anyway a problematic situation with following sequence:
790 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
791 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
792 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000793 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000794
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000795 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000796 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000797 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000799 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000800 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000802 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300803}
804
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
806 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000807
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000809 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000811 return
812 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000814 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000816 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000818 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000819 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000820 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000821 }
Himani Chawla4d908332020-08-31 12:30:20 +0530822 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000823 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000824 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
825 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
826 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
827 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000828 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000830}
831
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
833 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000834
dbainbri4d3a0dc2020-12-02 00:33:42 +0000835 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000836 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000837 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000838 if !dh.isSkipOnuConfigReconciling() {
839 dh.stopReconciling(ctx)
840 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000841 return
842 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000843 dh.pOnuTP.lockTpProcMutex()
844 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000845 pDevEntry.mutexPersOnuConfig.RLock()
846 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000847
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000848 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000850 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000851 if !dh.isSkipOnuConfigReconciling() {
852 dh.stopReconciling(ctx)
853 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000854 return
855 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000856 techProfsFound := false
857 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000858 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000859 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
860 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000861 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000862 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000863 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000864 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000865 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800866 for tpID := range uniData.PersTpPathMap {
867 // deadline context to ensure completion of background routines waited for
868 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
869 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000871
Girish Gowdra041dcb32020-11-16 16:54:30 -0800872 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
873 var wg sync.WaitGroup
874 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
876 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800877 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000878 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800879 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000880 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000881 if len(uniData.PersFlowParams) != 0 {
882 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000883 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000885 if !techProfsFound {
886 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
887 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000888 if !dh.isSkipOnuConfigReconciling() {
889 dh.stopReconciling(ctx)
890 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000891 return
892 }
893 if dh.isSkipOnuConfigReconciling() {
894 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
895 }
896 if !flowsFound {
897 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
898 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000899 if !dh.isSkipOnuConfigReconciling() {
900 dh.stopReconciling(ctx)
901 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000902 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903}
904
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
906 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000907
dbainbri4d3a0dc2020-12-02 00:33:42 +0000908 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000909 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000911 if !dh.isSkipOnuConfigReconciling() {
912 dh.stopReconciling(ctx)
913 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000914 return
915 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000916 pDevEntry.mutexPersOnuConfig.RLock()
917 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000918
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000919 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000920 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000921 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000922 if !dh.isSkipOnuConfigReconciling() {
923 dh.stopReconciling(ctx)
924 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000925 return
926 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000927 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000928 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000929 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
930 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000932 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000933 continue
934 }
935 if len(uniData.PersTpPathMap) == 0 {
936 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
937 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000938 // It doesn't make sense to configure any flows if no TPs are available
939 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000940 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000941 var uniPort *onuUniPort
942 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000943 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000944 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000945 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
946 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000947 if !dh.isSkipOnuConfigReconciling() {
948 dh.stopReconciling(ctx)
949 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950 return
951 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000952 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200953 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000954 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000955 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000957 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200958 // If this is the last flow for the device we need to announce it the waiting
959 // chReconcilingFlowsFinished channel
960 if flowsProcessed == len(uniData.PersFlowParams)-1 {
961 lastFlowToReconcile = true
962 }
mpagenko01e726e2020-10-23 09:45:29 +0000963 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000964 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000965 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000967 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200968 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000970 }
mpagenkof1fc3862021-02-16 10:09:52 +0000971 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000972 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000973 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000974 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000975 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200976 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000977 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000978 }
979 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000980 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000981 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
983 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
984 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200985 // this can't be used as global finished reconciling flag because
986 // assumes is getting called before the state machines for the last flow is completed,
987 // while this is not guaranteed.
988 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000989 }
990 if !flowsFound {
991 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
992 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000993 if !dh.isSkipOnuConfigReconciling() {
994 dh.stopReconciling(ctx)
995 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000996 return
997 }
998 if dh.isSkipOnuConfigReconciling() {
999 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001000 }
1001}
1002
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001003func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1004 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001005 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001006}
1007
dbainbri4d3a0dc2020-12-02 00:33:42 +00001008func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1009 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001010
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001013 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001014 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001015 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001016 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017
1018 // deadline context to ensure completion of background routines waited for
1019 //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 +05301020 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001022
1023 pDevEntry.resetKvProcessingErrorIndication()
1024
1025 var wg sync.WaitGroup
1026 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1028 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001029
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001030 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001031 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001032}
1033
mpagenko15ff4a52021-03-02 10:09:20 +00001034//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1035// before this change here return like this was used:
1036// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1037//was and is called in background - error return does not make sense
1038func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1039 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1040 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001041 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001042 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001043 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001044 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301045 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001046 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001047 return
Himani Chawla4d908332020-08-31 12:30:20 +05301048 }
mpagenko01e726e2020-10-23 09:45:29 +00001049
1050 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001052
dbainbri4d3a0dc2020-12-02 00:33:42 +00001053 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001054 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001056 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001057 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001059 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001060 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001062 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001063 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001064 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001065 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1066 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1067 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1068 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001069}
1070
mpagenkoc8bba412021-01-15 15:38:44 +00001071//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001072func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1073 apDownloadManager *adapterDownloadManager) error {
1074 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001075 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001076
1077 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001078 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1079 if pDevEntry == nil {
1080 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1081 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1082 }
1083
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001084 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001085 var inactiveImageID uint16
1086 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1087 dh.lockUpgradeFsm.Lock()
1088 defer dh.lockUpgradeFsm.Unlock()
1089 if dh.pOnuUpradeFsm == nil {
1090 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1091 if err == nil {
1092 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1093 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1094 "device-id": dh.deviceID, "error": err})
1095 }
1096 } else {
1097 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001098 "device-id": dh.deviceID, "error": err})
1099 }
mpagenko15ff4a52021-03-02 10:09:20 +00001100 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1101 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1102 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1103 if pUpgradeStatemachine != nil {
1104 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1105 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1106 "device-id": dh.deviceID, "error": err})
1107 }
1108 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1109 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1110 // for now a second start of download should work again
1111 } else { //should never occur
1112 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1113 "device-id": dh.deviceID})
1114 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001115 }
mpagenko80622a52021-02-09 16:53:23 +00001116 }
mpagenko15ff4a52021-03-02 10:09:20 +00001117 } else {
1118 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1119 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001120 }
1121 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001122 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1123 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001124 }
1125 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001126}
1127
mpagenkoc26d4c02021-05-06 14:27:57 +00001128//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1129// after the OnuImage has been downloaded to the adapter, called in background
1130func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1131 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1132
1133 var err error
1134 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1135 if pDevEntry == nil {
1136 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1137 return
1138 }
1139
1140 var inactiveImageID uint16
1141 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1142 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1143 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1144 dh.lockUpgradeFsm.Lock()
1145 defer dh.lockUpgradeFsm.Unlock()
1146 if dh.pOnuUpradeFsm == nil {
1147 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1148 // but none yet defined
1149 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1150 if err == nil {
1151 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001152 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001153 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1154 "device-id": dh.deviceID, "error": err})
1155 return
1156 }
1157 } else {
1158 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1159 "device-id": dh.deviceID, "error": err})
1160 }
1161 return
1162 }
1163 //OnuSw upgrade already running - restart (with possible abort of running)
1164 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1165 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1166 if pUpgradeStatemachine != nil {
1167 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1168 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1169 "device-id": dh.deviceID, "error": err})
1170 return
1171 }
1172 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1173 // for now a second start of download should work again - must still be initiated by user
1174 } else { //should never occur
1175 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1176 "device-id": dh.deviceID})
1177 }
1178 return
1179 }
1180 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1181 "device-id": dh.deviceID, "error": err})
1182}
1183
1184//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001185func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1186 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001187 var err error
1188 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1189 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1190 // 2.) activation of the inactive image
1191
1192 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1193 if pDevEntry == nil {
1194 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001195 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001196 }
1197 dh.lockUpgradeFsm.RLock()
1198 if dh.pOnuUpradeFsm != nil {
1199 dh.lockUpgradeFsm.RUnlock()
1200 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1201 dh.deviceID, dh.deviceID)
1202 if getErr != nil || onuVolthaDevice == nil {
1203 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001204 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001205 }
1206 // use the OnuVendor identification from this device for the internal unique name
1207 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1208 // 1.) check a started upgrade process and rely the activation request to it
1209 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001210 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001211 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1212 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001213 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001214 }
mpagenko183647c2021-06-08 15:25:04 +00001215 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1216 "device-id": dh.deviceID, "image-id": imageIdentifier})
1217 var pImageStates *voltha.ImageState
1218 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1219 pImageStates = &voltha.ImageState{}
1220 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1221 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1222 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1223 }
1224 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001225 } //else
1226 dh.lockUpgradeFsm.RUnlock()
1227
1228 // 2.) check if requested image-version equals the inactive one and start its activation
1229 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1230 var inactiveImageID uint16
1231 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1232 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1233 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001234 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001235 }
1236 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1237 if err == nil {
1238 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1239 inactiveImageID, aCommitRequest); err != nil {
1240 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1241 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001242 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001243 }
1244 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1245 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001246 var pImageStates *voltha.ImageState
1247 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1248 pImageStates := &voltha.ImageState{}
1249 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1250 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1251 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1252 }
1253 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001254 } //else
1255 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1256 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001257 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001258}
1259
1260//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001261func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1262 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001263 var err error
1264 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1265 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1266 // 2.) commitment of the active image
1267
1268 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1269 if pDevEntry == nil {
1270 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001271 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001272 }
1273 dh.lockUpgradeFsm.RLock()
1274 if dh.pOnuUpradeFsm != nil {
1275 dh.lockUpgradeFsm.RUnlock()
1276 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1277 dh.deviceID, dh.deviceID)
1278 if getErr != nil || onuVolthaDevice == nil {
1279 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001280 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001281 }
1282 // use the OnuVendor identification from this device for the internal unique name
1283 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1284 // 1.) check a started upgrade process and rely the commitment request to it
1285 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001286 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001287 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1288 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001289 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001290 }
mpagenko183647c2021-06-08 15:25:04 +00001291 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1292 "device-id": dh.deviceID, "image-id": imageIdentifier})
1293 var pImageStates *voltha.ImageState
1294 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1295 pImageStates := &voltha.ImageState{}
1296 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1297 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1298 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1299 }
1300 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001301 } //else
1302 dh.lockUpgradeFsm.RUnlock()
1303
mpagenko183647c2021-06-08 15:25:04 +00001304 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001305 var activeImageID uint16
1306 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1307 logger.Errorw(ctx, "get active image failed", log.Fields{
1308 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001309 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001310 }
1311 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1312 if err == nil {
1313 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1314 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1315 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001316 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001317 }
1318 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1319 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001320 var pImageStates *voltha.ImageState
1321 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1322 pImageStates := &voltha.ImageState{}
1323 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1324 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1325 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1326 }
1327 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001328 } //else
1329 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1330 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001331 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001332}
1333
mpagenkoaa3afe92021-05-21 16:20:58 +00001334func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1335 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1336 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001337 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001338 dh.lockUpgradeFsm.RLock()
1339 if dh.pOnuUpradeFsm != nil {
1340 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001341 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001342 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1343 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1344 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1345 } else {
1346 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1347 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1348 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1349 }
1350 } else {
1351 dh.lockUpgradeFsm.RUnlock()
1352 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1353 if dh.upgradeSuccess {
1354 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1355 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1356 } else {
1357 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1358 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1359 }
1360 }
1361}
1362
1363func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1364 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1365 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001366 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001367 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1368 dh.lockUpgradeFsm.RLock()
1369 if dh.pOnuUpradeFsm != nil {
1370 dh.lockUpgradeFsm.RUnlock()
1371 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1372 // by now just straightforward assume this to be true
1373 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1374 //nolint:misspell
1375 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1376 //nolint:misspell
1377 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1378 } else {
1379 dh.lockUpgradeFsm.RUnlock()
1380 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1381 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1382 }
1383}
1384
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001385func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1386
1387 var onuImageStatus *OnuImageStatus
1388
1389 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1390 if pDevEntry != nil {
1391 onuImageStatus = NewOnuImageStatus(pDevEntry)
1392 pDevEntry.mutexOnuImageStatus.Lock()
1393 pDevEntry.pOnuImageStatus = onuImageStatus
1394 pDevEntry.mutexOnuImageStatus.Unlock()
1395
1396 } else {
1397 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1398 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1399 }
1400 images, err := onuImageStatus.getOnuImageStatus(ctx)
1401 pDevEntry.mutexOnuImageStatus.Lock()
1402 pDevEntry.pOnuImageStatus = nil
1403 pDevEntry.mutexOnuImageStatus.Unlock()
1404 return images, err
1405}
1406
Himani Chawla6d2ae152020-09-02 13:11:20 +05301407// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001408// #####################################################################################
1409
1410// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301411// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001412
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1414 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001415}
1416
1417// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001419
dbainbri4d3a0dc2020-12-02 00:33:42 +00001420 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001421 var err error
1422
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001423 // populate what we know. rest comes later after mib sync
1424 dh.device.Root = false
1425 dh.device.Vendor = "OpenONU"
1426 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001427 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001428 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001429
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001430 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001431
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001432 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001433 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1434 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301435 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001436 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001438 log.Fields{"device-id": dh.deviceID})
1439 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001440
Himani Chawla4d908332020-08-31 12:30:20 +05301441 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001442 dh.ponPortNumber = dh.device.ParentPortNo
1443
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001444 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1445 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1446 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001448 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301449 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001450
1451 /*
1452 self._pon = PonPort.create(self, self._pon_port_number)
1453 self._pon.add_peer(self.parent_id, self._pon_port_number)
1454 self.logger.debug('adding-pon-port-to-agent',
1455 type=self._pon.get_port().type,
1456 admin_state=self._pon.get_port().admin_state,
1457 oper_status=self._pon.get_port().oper_status,
1458 )
1459 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001460 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001461 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001462 var ponPortNo uint32 = 1
1463 if dh.ponPortNumber != 0 {
1464 ponPortNo = dh.ponPortNumber
1465 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001466
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001467 pPonPort := &voltha.Port{
1468 PortNo: ponPortNo,
1469 Label: fmt.Sprintf("pon-%d", ponPortNo),
1470 Type: voltha.Port_PON_ONU,
1471 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301472 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001473 PortNo: ponPortNo}}, // Peer port is parent's port number
1474 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1476 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001477 e.Cancel(err)
1478 return
1479 }
1480 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001482 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001484}
1485
1486// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001488
dbainbri4d3a0dc2020-12-02 00:33:42 +00001489 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001490 var err error
1491 /*
1492 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1493 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1494 return nil
1495 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001496 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1497 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001498 e.Cancel(err)
1499 return
1500 }
1501
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001502 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001504 // reconcilement will be continued after mib download is done
1505 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001506
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001507 /*
1508 ############################################################################
1509 # Setup Alarm handler
1510 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1511 device.serial_number)
1512 ############################################################################
1513 # Setup PM configuration for this device
1514 # Pass in ONU specific options
1515 kwargs = {
1516 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1517 'heartbeat': self.heartbeat,
1518 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1519 }
1520 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1521 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1522 self.logical_device_id, device.serial_number,
1523 grouped=True, freq_override=False, **kwargs)
1524 pm_config = self._pm_metrics.make_proto()
1525 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1526 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1527 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1528
1529 # Note, ONU ID and UNI intf set in add_uni_port method
1530 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1531 ani_ports=[self._pon])
1532
1533 # Code to Run OMCI Test Action
1534 kwargs_omci_test_action = {
1535 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1536 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1537 }
1538 serial_number = device.serial_number
1539 self._test_request = OmciTestRequest(self.core_proxy,
1540 self.omci_agent, self.device_id,
1541 AniG, serial_number,
1542 self.logical_device_id,
1543 exclusive=False,
1544 **kwargs_omci_test_action)
1545
1546 self.enabled = True
1547 else:
1548 self.logger.info('onu-already-activated')
1549 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001550
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001552}
1553
1554// doStateConnected get the device info and update to voltha core
1555// for comparison of the original method (not that easy to uncomment): compare here:
1556// voltha-openolt-adapter/adaptercore/device_handler.go
1557// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001559
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301561 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001562 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001564}
1565
1566// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001568
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301570 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001571 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573
1574 /*
1575 // Synchronous call to update device state - this method is run in its own go routine
1576 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1577 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001578 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001579 return err
1580 }
1581 return nil
1582 */
1583}
1584
1585// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001587
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001589 var err error
1590
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001591 device := dh.device
1592 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001593 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001595 e.Cancel(err)
1596 return
1597 }
1598
1599 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001601 /*
1602 // Update the all ports state on that device to disable
1603 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001604 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001605 return er
1606 }
1607
1608 //Update the device oper state and connection status
1609 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1610 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1611 dh.device = cloned
1612
1613 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001614 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001615 return er
1616 }
1617
1618 //get the child device for the parent device
1619 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1620 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001621 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001622 return err
1623 }
1624 for _, onuDevice := range onuDevices.Items {
1625
1626 // Update onu state as down in onu adapter
1627 onuInd := oop.OnuIndication{}
1628 onuInd.OperState = "down"
1629 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1630 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1631 if er != nil {
1632 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001633 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634 //Do not return here and continue to process other ONUs
1635 }
1636 }
1637 // * Discovered ONUs entries need to be cleared , since after OLT
1638 // is up, it starts sending discovery indications again* /
1639 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001640 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001641 return nil
1642 */
Himani Chawla4d908332020-08-31 12:30:20 +05301643 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646}
1647
Himani Chawla6d2ae152020-09-02 13:11:20 +05301648// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649// #################################################################################
1650
1651// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301652// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001654//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001656 dh.lockDevice.RLock()
1657 pOnuDeviceEntry := dh.pOnuOmciDevice
1658 if aWait && pOnuDeviceEntry == nil {
1659 //keep the read sema short to allow for subsequent write
1660 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001662 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1663 // so it might be needed to wait here for that event with some timeout
1664 select {
1665 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001667 return nil
1668 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001670 // if written now, we can return the written value without sema
1671 return dh.pOnuOmciDevice
1672 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001673 }
mpagenko3af1f032020-06-10 08:53:41 +00001674 dh.lockDevice.RUnlock()
1675 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676}
1677
Himani Chawla6d2ae152020-09-02 13:11:20 +05301678//setOnuDeviceEntry sets the ONU device entry within the handler
1679func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001680 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681 dh.lockDevice.Lock()
1682 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001683 dh.pOnuOmciDevice = apDeviceEntry
1684 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001685 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301686 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001687 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688}
1689
Himani Chawla6d2ae152020-09-02 13:11:20 +05301690//addOnuDeviceEntry creates a new ONU device or returns the existing
1691func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001692 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001693
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 if deviceEntry == nil {
1696 /* costum_me_map in python code seems always to be None,
1697 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1698 /* also no 'clock' argument - usage open ...*/
1699 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001700 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001701 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001702 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301703 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001704 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001705 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001706 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001707 // fire deviceEntry ready event to spread to possibly waiting processing
1708 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001710 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001711 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001712 }
1713 // might be updated with some error handling !!!
1714 return nil
1715}
1716
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1718 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001719 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1720
1721 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001722
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001724 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001726 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1727 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001728 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 if err := dh.storePersistentData(ctx); err != nil {
1730 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001731 log.Fields{"device-id": dh.deviceID, "err": err})
1732 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001733 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001734 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001736 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1737 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001739 }
1740 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001742 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001743
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001744 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001745 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001746 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Debugw(ctx, "reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001748 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001749 dh.stopReconciling(ctx)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001750 } else {
1751 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001752 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001753 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001754 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1755 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1756 // in python code it looks as the started onu_omci_device might have been updated with some new instance state of the core device
mpagenkoaf801632020-07-03 10:00:42 +00001757 // but I would not know why, and the go code anyway does not work with the device directly anymore in the OnuDeviceEntry
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001758 // so let's just try to keep it simple ...
1759 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001761 if err != nil || device == nil {
1762 //TODO: needs to handle error scenarios
1763 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1764 return errors.New("Voltha Device not found")
1765 }
1766 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001767
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001769 return err
mpagenko3af1f032020-06-10 08:53:41 +00001770 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001771
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001772 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001773
1774 /* this might be a good time for Omci Verify message? */
1775 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001777 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001778 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780
1781 /* give the handler some time here to wait for the OMCi verification result
1782 after Timeout start and try MibUpload FSM anyway
1783 (to prevent stopping on just not supported OMCI verification from ONU) */
1784 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001785 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001787 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789 }
1790
1791 /* In py code it looks earlier (on activate ..)
1792 # Code to Run OMCI Test Action
1793 kwargs_omci_test_action = {
1794 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1795 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1796 }
1797 serial_number = device.serial_number
1798 self._test_request = OmciTestRequest(self.core_proxy,
1799 self.omci_agent, self.device_id,
1800 AniG, serial_number,
1801 self.logical_device_id,
1802 exclusive=False,
1803 **kwargs_omci_test_action)
1804 ...
1805 # Start test requests after a brief pause
1806 if not self._test_request_started:
1807 self._test_request_started = True
1808 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1809 reactor.callLater(tststart, self._test_request.start_collector)
1810
1811 */
1812 /* which is then: in omci_test_request.py : */
1813 /*
1814 def start_collector(self, callback=None):
1815 """
1816 Start the collection loop for an adapter if the frequency > 0
1817
1818 :param callback: (callable) Function to call to collect PM data
1819 """
1820 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1821 if callback is None:
1822 callback = self.perform_test_omci
1823
1824 if self.lc is None:
1825 self.lc = LoopingCall(callback)
1826
1827 if self.default_freq > 0:
1828 self.lc.start(interval=self.default_freq / 10)
1829
1830 def perform_test_omci(self):
1831 """
1832 Perform the initial test request
1833 """
1834 ani_g_entities = self._device.configuration.ani_g_entities
1835 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1836 is not None else None
1837 self._entity_id = ani_g_entities_ids[0]
1838 self.logger.info('perform-test', entity_class=self._entity_class,
1839 entity_id=self._entity_id)
1840 try:
1841 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1842 result = yield self._device.omci_cc.send(frame)
1843 if not result.fields['omci_message'].fields['success_code']:
1844 self.logger.info('Self-Test Submitted Successfully',
1845 code=result.fields[
1846 'omci_message'].fields['success_code'])
1847 else:
1848 raise TestFailure('Test Failure: {}'.format(
1849 result.fields['omci_message'].fields['success_code']))
1850 except TimeoutError as e:
1851 self.deferred.errback(failure.Failure(e))
1852
1853 except Exception as e:
1854 self.logger.exception('perform-test-Error', e=e,
1855 class_id=self._entity_class,
1856 entity_id=self._entity_id)
1857 self.deferred.errback(failure.Failure(e))
1858
1859 */
1860
1861 // PM related heartbeat??? !!!TODO....
1862 //self._heartbeat.enabled = True
1863
mpagenko1cc3cb42020-07-27 15:24:38 +00001864 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1865 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1866 * as further OltAdapter processing may rely on the deviceReason event 'MibUploadDone' as a result of the FSM processing
Himani Chawla4d908332020-08-31 12:30:20 +05301867 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001868 */
1869 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001870 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001871 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001872 if pMibUlFsm.Is(ulStDisabled) {
1873 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001874 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001875 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301876 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301878 //Determine ONU status and start/re-start MIB Synchronization tasks
1879 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001880 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301881 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001882 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001883 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001884 }
Himani Chawla4d908332020-08-31 12:30:20 +05301885 } else {
1886 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001888 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301889 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001891 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001892 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001894 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001895 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001896 }
1897 } else {
dbainbri