blob: 4643e9124cc3bd34ea65b8f915a1792ac93bb5ab [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"
22 "encoding/hex"
23 "errors"
24 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000025 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000026 "sync"
27 "time"
28
29 "github.com/gogo/protobuf/proto"
30 "github.com/golang/protobuf/ptypes"
31 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000032 me "github.com/opencord/omci-lib-go/generated"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000033 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
mpagenkoaf801632020-07-03 10:00:42 +000034 "github.com/opencord/voltha-lib-go/v3/pkg/db"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000035 "github.com/opencord/voltha-lib-go/v3/pkg/log"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000036 vc "github.com/opencord/voltha-protos/v3/go/common"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000037 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
38 oop "github.com/opencord/voltha-protos/v3/go/openolt"
39 "github.com/opencord/voltha-protos/v3/go/voltha"
40)
41
42/*
43// Constants for number of retries and for timeout
44const (
45 MaxRetry = 10
46 MaxTimeOutInMs = 500
47)
48*/
49
mpagenko1cc3cb42020-07-27 15:24:38 +000050const (
51 // events of Device FSM
52 devEvDeviceInit = "devEvDeviceInit"
53 devEvGrpcConnected = "devEvGrpcConnected"
54 devEvGrpcDisconnected = "devEvGrpcDisconnected"
55 devEvDeviceUpInd = "devEvDeviceUpInd"
56 devEvDeviceDownInd = "devEvDeviceDownInd"
57)
58const (
59 // states of Device FSM
60 devStNull = "devStNull"
61 devStDown = "devStDown"
62 devStInit = "devStInit"
63 devStConnected = "devStConnected"
64 devStUp = "devStUp"
65)
66
Holger Hildebrandt24d51952020-05-04 14:03:42 +000067//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
68const (
69 pon = voltha.EventSubCategory_PON
70 olt = voltha.EventSubCategory_OLT
71 ont = voltha.EventSubCategory_ONT
72 onu = voltha.EventSubCategory_ONU
73 nni = voltha.EventSubCategory_NNI
74 service = voltha.EventCategory_SERVICE
75 security = voltha.EventCategory_SECURITY
76 equipment = voltha.EventCategory_EQUIPMENT
77 processing = voltha.EventCategory_PROCESSING
78 environment = voltha.EventCategory_ENVIRONMENT
79 communication = voltha.EventCategory_COMMUNICATION
80)
81
82const (
83 cEventObjectType = "ONU"
84)
85const (
86 cOnuActivatedEvent = "ONU_ACTIVATED"
87)
88
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000089//DeviceHandler will interact with the ONU ? device.
90type DeviceHandler struct {
91 deviceID string
92 DeviceType string
93 adminState string
94 device *voltha.Device
95 logicalDeviceID string
96 ProxyAddressID string
97 ProxyAddressType string
Holger Hildebrandt24d51952020-05-04 14:03:42 +000098 parentId string
99 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000100
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000101 coreProxy adapterif.CoreProxy
102 AdapterProxy adapterif.AdapterProxy
103 EventProxy adapterif.EventProxy
104
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000105 pOpenOnuAc *OpenONUAC
106 pDeviceStateFsm *fsm.FSM
107 pPonPort *voltha.Port
mpagenko3af1f032020-06-10 08:53:41 +0000108 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000109 pOnuOmciDevice *OnuDeviceEntry
mpagenkoaf801632020-07-03 10:00:42 +0000110 pOnuTP *OnuUniTechProf
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000111 exitChannel chan int
112 lockDevice sync.RWMutex
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000113 pOnuIndication *oop.OnuIndication
mpagenko3af1f032020-06-10 08:53:41 +0000114 deviceReason string
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000115 pLockStateFsm *LockStateFsm
116 pUnlockStateFsm *LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000117
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000118 //flowMgr *OpenOltFlowMgr
119 //eventMgr *OpenOltEventMgr
120 //resourceMgr *rsrcMgr.OpenOltResourceMgr
121
122 //discOnus sync.Map
123 //onus sync.Map
124 //portStats *OpenOltStatisticsMgr
125 //metrics *pmmetrics.PmMetrics
126 stopCollector chan bool
127 stopHeartbeatCheck chan bool
128 activePorts sync.Map
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000129 uniEntityMap map[uint32]*OnuUniPort
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000130}
131
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000132//NewDeviceHandler creates a new device handler
133func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *DeviceHandler {
134 var dh DeviceHandler
135 dh.coreProxy = cp
136 dh.AdapterProxy = ap
137 dh.EventProxy = ep
138 cloned := (proto.Clone(device)).(*voltha.Device)
139 dh.deviceID = cloned.Id
140 dh.DeviceType = cloned.Type
141 dh.adminState = "up"
142 dh.device = cloned
143 dh.pOpenOnuAc = adapter
144 dh.exitChannel = make(chan int, 1)
145 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000146 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000147 dh.stopCollector = make(chan bool, 2)
148 dh.stopHeartbeatCheck = make(chan bool, 2)
149 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
150 dh.activePorts = sync.Map{}
151 //TODO initialize the support classes.
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000152 dh.uniEntityMap = make(map[uint32]*OnuUniPort)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153
154 // Device related state machine
155 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000156 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000157 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000158 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
159 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
160 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
161 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
162 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163 },
164 fsm.Callbacks{
mpagenko1cc3cb42020-07-27 15:24:38 +0000165 "before_event": func(e *fsm.Event) { dh.logStateChange(e) },
166 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(e) },
167 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(e) },
168 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(e) },
169 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(e) },
170 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(e) },
171 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(e) },
172 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173 },
174 )
mpagenkoaf801632020-07-03 10:00:42 +0000175
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000176 return &dh
177}
178
179// start save the device to the data model
180func (dh *DeviceHandler) Start(ctx context.Context) {
divyadesai4d299552020-08-18 07:13:49 +0000181 logger.Debugw("starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000182 // Add the initial device to the local model
183 logger.Debug("device-handler-started")
184}
185
186// stop stops the device dh. Not much to do for now
187func (dh *DeviceHandler) stop(ctx context.Context) {
188 logger.Debug("stopping-device-handler")
189 dh.exitChannel <- 1
190}
191
192// ##########################################################################################
193// DeviceHandler methods that implement the adapters interface requests ##### begin #########
194
195//AdoptDevice adopts the OLT device
196func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000197 logger.Debugw("Adopt_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000198
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000199 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000200 if dh.pDeviceStateFsm.Is(devStNull) {
201 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000202 logger.Errorw("Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
203 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000204 logger.Debugw("Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000205 } else {
206 logger.Debug("AdoptDevice: Agent/device init already done")
207 }
208
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000209}
210
211//ProcessInterAdapterMessage sends the proxied messages to the target device
212// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
213// is meant, and then send the unmarshalled omci message to this onu
214func (dh *DeviceHandler) ProcessInterAdapterMessage(msg *ic.InterAdapterMessage) error {
215 msgID := msg.Header.Id
216 msgType := msg.Header.Type
217 fromTopic := msg.Header.FromTopic
218 toTopic := msg.Header.ToTopic
219 toDeviceID := msg.Header.ToDeviceId
220 proxyDeviceID := msg.Header.ProxyDeviceId
221 logger.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
222 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
223
224 switch msgType {
225 case ic.InterAdapterMessageType_OMCI_REQUEST:
226 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000227 msgBody := msg.GetBody()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228 omciMsg := &ic.InterAdapterOmciMessage{}
229 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000230 logger.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000231 "device-id": dh.deviceID, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000232 return err
233 }
234
235 //assuming omci message content is hex coded!
236 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000237 logger.Debugw("inter-adapter-recv-omci", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000238 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239 //receive_message(omci_msg.message)
mpagenko3af1f032020-06-10 08:53:41 +0000240 pDevEntry := dh.GetOnuDeviceEntry(true)
241 if pDevEntry != nil {
242 return pDevEntry.PDevOmciCC.ReceiveMessage(context.TODO(), omciMsg.Message)
243 } else {
divyadesai4d299552020-08-18 07:13:49 +0000244 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000245 return errors.New("No valid OnuDevice")
246 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 }
248 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
249 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 msgBody := msg.GetBody()
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 onu_indication := &oop.OnuIndication{}
252 if err := ptypes.UnmarshalAny(msgBody, onu_indication); err != nil {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000253 logger.Warnw("cannot-unmarshal-onu-indication-msg-body", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000254 "device-id": dh.deviceID, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 return err
256 }
257
258 onu_operstate := onu_indication.GetOperState()
259 logger.Debugw("inter-adapter-recv-onu-ind", log.Fields{"OnuId": onu_indication.GetOnuId(),
260 "AdminState": onu_indication.GetAdminState(), "OperState": onu_operstate,
261 "SNR": onu_indication.GetSerialNumber()})
262
mpagenko3af1f032020-06-10 08:53:41 +0000263 //interface related functions might be error checked ....
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000264 if onu_operstate == "up" {
265 dh.create_interface(onu_indication)
266 } else if (onu_operstate == "down") || (onu_operstate == "unreachable") {
mpagenko3af1f032020-06-10 08:53:41 +0000267 dh.updateInterface(onu_indication)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268 } else {
269 logger.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onu_indication.GetOnuId()})
270 return errors.New("InvalidOperState")
271 }
272 }
mpagenkoaf801632020-07-03 10:00:42 +0000273 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
274 {
275 if dh.pOnuTP == nil {
276 //should normally not happen ...
277 logger.Warnw("onuTechProf instance not set up for DLMsg request - ignoring request",
divyadesai4d299552020-08-18 07:13:49 +0000278 log.Fields{"device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +0000279 return errors.New("TechProfile DLMsg request while onuTechProf instance not setup")
280 }
mpagenko1cc3cb42020-07-27 15:24:38 +0000281 if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock") {
282 // I've seen cases for this request, where the device was already stopped
divyadesai4d299552020-08-18 07:13:49 +0000283 logger.Warnw("TechProf stopped: device-unreachable", log.Fields{"device-id": dh.deviceID})
mpagenko1cc3cb42020-07-27 15:24:38 +0000284 return errors.New("device-unreachable")
285 }
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000286
mpagenkoaf801632020-07-03 10:00:42 +0000287 msgBody := msg.GetBody()
288 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
289 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
290 logger.Warnw("cannot-unmarshal-techprof-msg-body", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000291 "device-id": dh.deviceID, "error": err})
mpagenkoaf801632020-07-03 10:00:42 +0000292 return err
293 }
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000294
mpagenkoaf801632020-07-03 10:00:42 +0000295 // we have to lock access to TechProfile processing based on different messageType calls or
296 // even to fast subsequent calls of the same messageType
297 dh.pOnuTP.lockTpProcMutex()
298 // lock hangs as long as below decoupled or other related TechProfile processing is active
299 if bTpModify := dh.pOnuTP.updateOnuUniTpPath(techProfMsg.UniId, techProfMsg.Path); bTpModify == true {
300 // if there has been some change for some uni TechProfilePath
301 //in order to allow concurrent calls to other dh instances we do not wait for execution here
302 //but doing so we can not indicate problems to the caller (who does what with that then?)
303 //by now we just assume straightforward successful execution
304 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
305 // possible problems to the caller later autonomously
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000306
mpagenko3dbcdd22020-07-22 07:38:45 +0000307 // deadline context to ensure completion of background routines waited for
308 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
309 deadline := time.Now().Add(30 * time.Second) //allowed run time to finish before execution
310 dctx, cancel := context.WithDeadline(context.Background(), deadline)
311
mpagenko1cc3cb42020-07-27 15:24:38 +0000312 dh.pOnuTP.resetProcessingErrorIndication()
mpagenkoaf801632020-07-03 10:00:42 +0000313 var wg sync.WaitGroup
314 wg.Add(2) // for the 2 go routines to finish
mpagenko3dbcdd22020-07-22 07:38:45 +0000315 // attention: deadline completion check and wg.Done is to be done in both routines
316 go dh.pOnuTP.configureUniTp(dctx, techProfMsg.UniId, techProfMsg.Path, &wg)
317 go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
mpagenkoaf801632020-07-03 10:00:42 +0000318 //the wait.. function is responsible for tpProcMutex.Unlock()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000319 err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //wait for background process to finish and collect their result
mpagenko1cc3cb42020-07-27 15:24:38 +0000320 return err
mpagenkoaf801632020-07-03 10:00:42 +0000321 }
mpagenko1cc3cb42020-07-27 15:24:38 +0000322 // no change, nothing really to do
323 dh.pOnuTP.unlockTpProcMutex()
324 //return success
325 return nil
mpagenkoaf801632020-07-03 10:00:42 +0000326 }
327 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
328 {
329 if dh.pOnuTP == nil {
330 //should normally not happen ...
331 logger.Warnw("onuTechProf instance not set up for DelGem request - ignoring request",
divyadesai4d299552020-08-18 07:13:49 +0000332 log.Fields{"device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +0000333 return errors.New("TechProfile DelGem request while onuTechProf instance not setup")
334 }
335
336 msgBody := msg.GetBody()
337 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
338 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
339 logger.Warnw("cannot-unmarshal-delete-gem-msg-body", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000340 "device-id": dh.deviceID, "error": err})
mpagenkoaf801632020-07-03 10:00:42 +0000341 return err
342 }
343
344 //compare TECH_PROFILE_DOWNLOAD_REQUEST
345 dh.pOnuTP.lockTpProcMutex()
mpagenko3dbcdd22020-07-22 07:38:45 +0000346
347 // deadline context to ensure completion of background routines waited for
348 deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
349 dctx, cancel := context.WithDeadline(context.Background(), deadline)
350
mpagenko1cc3cb42020-07-27 15:24:38 +0000351 dh.pOnuTP.resetProcessingErrorIndication()
mpagenkoaf801632020-07-03 10:00:42 +0000352 var wg sync.WaitGroup
353 wg.Add(1) // for the 1 go routine to finish
mpagenko3dbcdd22020-07-22 07:38:45 +0000354 go dh.pOnuTP.deleteTpResource(dctx, delGemPortMsg.UniId, delGemPortMsg.TpPath,
mpagenkoaf801632020-07-03 10:00:42 +0000355 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
356 //the wait.. function is responsible for tpProcMutex.Unlock()
mpagenko1cc3cb42020-07-27 15:24:38 +0000357 err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
358 return err
mpagenkoaf801632020-07-03 10:00:42 +0000359 }
360 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
361 {
362 if dh.pOnuTP == nil {
363 //should normally not happen ...
364 logger.Warnw("onuTechProf instance not set up for DelTcont request - ignoring request",
divyadesai4d299552020-08-18 07:13:49 +0000365 log.Fields{"device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +0000366 return errors.New("TechProfile DelTcont request while onuTechProf instance not setup")
367 }
368
369 msgBody := msg.GetBody()
370 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
371 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
372 logger.Warnw("cannot-unmarshal-delete-tcont-msg-body", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000373 "device-id": dh.deviceID, "error": err})
mpagenkoaf801632020-07-03 10:00:42 +0000374 return err
375 }
376
377 //compare TECH_PROFILE_DOWNLOAD_REQUEST
378 dh.pOnuTP.lockTpProcMutex()
379 if bTpModify := dh.pOnuTP.updateOnuUniTpPath(delTcontMsg.UniId, ""); bTpModify == true {
mpagenko3dbcdd22020-07-22 07:38:45 +0000380 // deadline context to ensure completion of background routines waited for
381 deadline := time.Now().Add(10 * time.Second) //allowed run time to finish before execution
382 dctx, cancel := context.WithDeadline(context.Background(), deadline)
383
mpagenko1cc3cb42020-07-27 15:24:38 +0000384 dh.pOnuTP.resetProcessingErrorIndication()
mpagenkoaf801632020-07-03 10:00:42 +0000385 var wg sync.WaitGroup
mpagenko3dbcdd22020-07-22 07:38:45 +0000386 wg.Add(2) // for the 2 go routines to finish
387 go dh.pOnuTP.deleteTpResource(dctx, delTcontMsg.UniId, delTcontMsg.TpPath,
mpagenkoaf801632020-07-03 10:00:42 +0000388 cResourceTcont, delTcontMsg.AllocId, &wg)
389 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
mpagenko3dbcdd22020-07-22 07:38:45 +0000390 go dh.pOnuTP.updateOnuTpPathKvStore(dctx, &wg)
mpagenkoaf801632020-07-03 10:00:42 +0000391 //the wait.. function is responsible for tpProcMutex.Unlock()
mpagenko1cc3cb42020-07-27 15:24:38 +0000392 err := dh.pOnuTP.waitForTpCompletion(cancel, &wg) //let that also run off-line to let the IA messaging return!
393 return err
mpagenkoaf801632020-07-03 10:00:42 +0000394 }
mpagenko1cc3cb42020-07-27 15:24:38 +0000395 dh.pOnuTP.unlockTpProcMutex()
396 //return success
397 return nil
mpagenkoaf801632020-07-03 10:00:42 +0000398 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000399 default:
400 {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000401 logger.Errorw("inter-adapter-unhandled-type", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +0000402 "device-id": dh.deviceID, "msgType": msg.Header.Type})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000403 return errors.New("unimplemented")
404 }
405 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000406 return nil
407}
408
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000409//DisableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenko3af1f032020-06-10 08:53:41 +0000410// TODO!!! Clarify usage of this method, it is for sure not used within ONOS (OLT) device disable
411// maybe it is obsolete by now
ozgecanetsiafce57b12020-05-25 14:39:35 +0300412func (dh *DeviceHandler) DisableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000413 logger.Debugw("disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000414
mpagenko3af1f032020-06-10 08:53:41 +0000415 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly - inblock
416 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
417 if dh.deviceReason != "omci-admin-lock" {
418 // disable UNI ports/ONU
419 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
420 // here the result of the processing is not checked (trusted in background) *****
421 if dh.pLockStateFsm == nil {
422 dh.createUniLockFsm(true, UniAdminStateDone)
423 } else { //LockStateFSM already init
424 dh.pLockStateFsm.SetSuccessEvent(UniAdminStateDone)
425 dh.runUniLockFsm(true)
426 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300427
mpagenko3af1f032020-06-10 08:53:41 +0000428 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "omci-admin-lock"); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000429 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +0000430 }
431 dh.deviceReason = "omci-admin-lock"
432 //200604: ConnState improved to 'unreachable' (was not set in python-code), OperState 'unknown' seems to be best choice
433 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
434 voltha.OperStatus_UNKNOWN); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000435 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +0000436 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300437 }
438}
439
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000440//ReenableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
mpagenko3af1f032020-06-10 08:53:41 +0000441// TODO!!! Clarify usage of this method, compare above DisableDevice, usage may clarify resulting states
442// maybe it is obsolete by now
ozgecanetsiafce57b12020-05-25 14:39:35 +0300443func (dh *DeviceHandler) ReenableDevice(device *voltha.Device) {
divyadesai4d299552020-08-18 07:13:49 +0000444 logger.Debugw("reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000445
446 // TODO!!! ConnectStatus and OperStatus to be set here could be more accurate, for now just ...(like python code)
ozgecanetsiafce57b12020-05-25 14:39:35 +0300447 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE,
448 voltha.OperStatus_ACTIVE); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000449 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300450 }
451
mpagenko3af1f032020-06-10 08:53:41 +0000452 // TODO!!! DeviceReason to be set here could be more accurate, for now just ...(like python code)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000453 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000454 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiafce57b12020-05-25 14:39:35 +0300455 }
mpagenko3af1f032020-06-10 08:53:41 +0000456 dh.deviceReason = "initial-mib-downloaded"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000457
458 // enable ONU/UNI ports
459 // *** should generate UniAdminStateDone event - unrelated to DeviceProcStatusUpdate!!
460 // here the result of the processing is not checked (trusted in background) *****
461 if dh.pUnlockStateFsm == nil {
462 dh.createUniLockFsm(false, UniAdminStateDone)
463 } else { //UnlockStateFSM already init
mpagenko3af1f032020-06-10 08:53:41 +0000464 dh.pUnlockStateFsm.SetSuccessEvent(UniAdminStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000465 dh.runUniLockFsm(false)
466 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300467}
468
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000469func (dh *DeviceHandler) ReconcileDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000470 logger.Debugw("reconcile-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000471 if err := dh.pOnuTP.restoreFromOnuTpPathKvStore(context.TODO()); err != nil {
472 return err
473 }
474 // TODO: further actions - init PON, metrics, reload DB ...
475 return nil
476}
477
478func (dh *DeviceHandler) DeleteDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000479 logger.Debugw("delete-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000480 if err := dh.pOnuTP.deleteOnuTpPathKvStore(context.TODO()); err != nil {
481 return err
482 }
483 // TODO: further actions - stop metrics and FSMs, remove device ...
484 return nil
485}
486
ozgecanetsiae11479f2020-07-06 09:44:47 +0300487func (dh *DeviceHandler) RebootDevice(device *voltha.Device) error {
divyadesai4d299552020-08-18 07:13:49 +0000488 logger.Debugw("reboot-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300489 if device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
divyadesai4d299552020-08-18 07:13:49 +0000490 logger.Errorw("device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300491 return errors.New("device-unreachable")
492 }
493 dh.pOnuOmciDevice.Reboot(context.TODO())
494 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_UNREACHABLE,
495 voltha.OperStatus_DISCOVERED); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000496 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300497 return err
498 }
499 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "rebooting-onu"); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000500 logger.Errorw("error-updating-reason-state", log.Fields{"device-id": dh.deviceID, "error": err})
ozgecanetsiae11479f2020-07-06 09:44:47 +0300501 return err
502 }
503 dh.deviceReason = "rebooting-onu"
504 return nil
505}
506
507//GetOfpPortInfo returns the Voltha PortCapabilty with the logical port
508//func (dh *DeviceHandler) GetOfpPortInfo(device *voltha.Device,
509// portNo int64) (*ic.PortCapability, error) {
510// logger.Debugw("GetOfpPortInfo start", log.Fields{"deviceID": device.Id, "portNo": portNo})
511
512//function body as per OLTAdapter handler code
513// adapted with values from py dapter code
514// if pUniPort, exist := dh.uniEntityMap[uint32(portNo)]; exist {
515// var macOctets [6]uint8
516// macOctets[5] = 0x08
517// macOctets[4] = uint8(dh.ponPortNumber >> 8)
518// macOctets[3] = uint8(dh.ponPortNumber)
519// macOctets[2] = uint8(portNo >> 16)
520// macOctets[1] = uint8(portNo >> 8)
521// macOctets[0] = uint8(portNo)
522// hwAddr := genMacFromOctets(macOctets)
523// capacity := uint32(of.OfpPortFeatures_OFPPF_1GB_FD | of.OfpPortFeatures_OFPPF_FIBER)
524// name := device.SerialNumber + "-" + strconv.FormatUint(uint64(pUniPort.macBpNo), 10)
525// ofUniPortState := of.OfpPortState_OFPPS_LINK_DOWN
526// if pUniPort.operState == vc.OperStatus_ACTIVE {
527// ofUniPortState = of.OfpPortState_OFPPS_LIVE
528// }
529// logger.Debugw("setting LogicalPort", log.Fields{"with-name": name,
530// "withUniPort": pUniPort.name, "withMacBase": hwAddr, "OperState": ofUniPortState})
531
532// return &ic.PortCapability{
533// Port: &voltha.LogicalPort{
534// OfpPort: &of.OfpPort{
535// Name: name,
536// //HwAddr: macAddressToUint32Array(dh.device.MacAddress),
537// HwAddr: macAddressToUint32Array(hwAddr),
538// Config: 0,
539// State: uint32(ofUniPortState),
540// Curr: capacity,
541// Advertised: capacity,
542// Peer: capacity,
543// CurrSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
544// MaxSpeed: uint32(of.OfpPortFeatures_OFPPF_1GB_FD),
545// },
546// DeviceId: device.Id,
547// DevicePortNo: uint32(portNo),
548// },
549// }, nil
550// }
551// logger.Warnw("No UniPort found - abort", log.Fields{"for PortNo": uint32(portNo)})
552// return nil, errors.New("UniPort not found")
553//}
554
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000555// DeviceHandler methods that implement the adapters interface requests## end #########
556// #####################################################################################
557
558// ################ to be updated acc. needs of ONU Device ########################
559// DeviceHandler StateMachine related state transition methods ##### begin #########
560
561func (dh *DeviceHandler) logStateChange(e *fsm.Event) {
562 logger.Debugw("Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.deviceID})
563}
564
565// doStateInit provides the device update to the core
566func (dh *DeviceHandler) doStateInit(e *fsm.Event) {
567
568 logger.Debug("doStateInit-started")
569 var err error
570
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000571 // populate what we know. rest comes later after mib sync
572 dh.device.Root = false
573 dh.device.Vendor = "OpenONU"
574 dh.device.Model = "go"
575 dh.device.Reason = "activating-onu"
mpagenko3af1f032020-06-10 08:53:41 +0000576 dh.deviceReason = "activating-onu"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000577
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000578 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000579 dh.coreProxy.DeviceUpdate(context.TODO(), dh.device)
580
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000581 dh.parentId = dh.device.ParentId
582 dh.ponPortNumber = dh.device.ParentPortNo
583
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000584 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
585 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
586 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
divyadesai4d299552020-08-18 07:13:49 +0000587 logger.Debugw("device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000588 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000589 "ParentId": dh.parentId, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000590
591 /*
592 self._pon = PonPort.create(self, self._pon_port_number)
593 self._pon.add_peer(self.parent_id, self._pon_port_number)
594 self.logger.debug('adding-pon-port-to-agent',
595 type=self._pon.get_port().type,
596 admin_state=self._pon.get_port().admin_state,
597 oper_status=self._pon.get_port().oper_status,
598 )
599 */
600 logger.Debug("adding-pon-port")
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000601 var ponPortNo uint32 = 1
602 if dh.ponPortNumber != 0 {
603 ponPortNo = dh.ponPortNumber
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000604 }
605
606 pPonPort := &voltha.Port{
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000607 PortNo: ponPortNo,
608 Label: fmt.Sprintf("pon-%d", ponPortNo),
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000609 Type: voltha.Port_PON_ONU,
610 OperStatus: voltha.OperStatus_ACTIVE,
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000611 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentId, // Peer device is OLT
612 PortNo: ponPortNo}}, // Peer port is parent's port number
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000613 }
614 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, pPonPort); err != nil {
615 logger.Fatalf("Device FSM: PortCreated-failed-%s", err)
616 e.Cancel(err)
617 return
618 }
619 logger.Debug("doStateInit-done")
620}
621
622// postInit setups the DeviceEntry for the conerned device
623func (dh *DeviceHandler) postInit(e *fsm.Event) {
624
625 logger.Debug("postInit-started")
626 var err error
627 /*
628 dh.Client = oop.NewOpenoltClient(dh.clientCon)
629 dh.pTransitionMap.Handle(ctx, GrpcConnected)
630 return nil
631 */
mpagenko3af1f032020-06-10 08:53:41 +0000632 if err = dh.AddOnuDeviceEntry(context.TODO()); err != nil {
633 logger.Fatalf("Device FSM: AddOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000634 e.Cancel(err)
635 return
636 }
637
638 /*
639 ############################################################################
640 # Setup Alarm handler
641 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
642 device.serial_number)
643 ############################################################################
644 # Setup PM configuration for this device
645 # Pass in ONU specific options
646 kwargs = {
647 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
648 'heartbeat': self.heartbeat,
649 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
650 }
651 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
652 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
653 self.logical_device_id, device.serial_number,
654 grouped=True, freq_override=False, **kwargs)
655 pm_config = self._pm_metrics.make_proto()
656 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
657 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
658 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
659
660 # Note, ONU ID and UNI intf set in add_uni_port method
661 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
662 ani_ports=[self._pon])
663
664 # Code to Run OMCI Test Action
665 kwargs_omci_test_action = {
666 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
667 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
668 }
669 serial_number = device.serial_number
670 self._test_request = OmciTestRequest(self.core_proxy,
671 self.omci_agent, self.device_id,
672 AniG, serial_number,
673 self.logical_device_id,
674 exclusive=False,
675 **kwargs_omci_test_action)
676
677 self.enabled = True
678 else:
679 self.logger.info('onu-already-activated')
680 */
681 logger.Debug("postInit-done")
682}
683
684// doStateConnected get the device info and update to voltha core
685// for comparison of the original method (not that easy to uncomment): compare here:
686// voltha-openolt-adapter/adaptercore/device_handler.go
687// -> this one obviously initiates all communication interfaces of the device ...?
688func (dh *DeviceHandler) doStateConnected(e *fsm.Event) {
689
690 logger.Debug("doStateConnected-started")
691 var err error
692 err = errors.New("Device FSM: function not implemented yet!")
693 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000694 logger.Debug("doStateConnected-done")
Matteo Scandolod132c0e2020-04-24 17:06:25 -0700695 return
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000696}
697
698// doStateUp handle the onu up indication and update to voltha core
699func (dh *DeviceHandler) doStateUp(e *fsm.Event) {
700
701 logger.Debug("doStateUp-started")
702 var err error
703 err = errors.New("Device FSM: function not implemented yet!")
704 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000705 logger.Debug("doStateUp-done")
Matteo Scandolod132c0e2020-04-24 17:06:25 -0700706 return
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000707
708 /*
709 // Synchronous call to update device state - this method is run in its own go routine
710 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
711 voltha.OperStatus_ACTIVE); err != nil {
712 logger.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
713 return err
714 }
715 return nil
716 */
717}
718
719// doStateDown handle the onu down indication
720func (dh *DeviceHandler) doStateDown(e *fsm.Event) {
721
722 logger.Debug("doStateDown-started")
723 var err error
724
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000725 device := dh.device
726 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000727 /*TODO: needs to handle error scenarios */
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000728 logger.Error("Failed to fetch handler device")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000729 e.Cancel(err)
730 return
731 }
732
733 cloned := proto.Clone(device).(*voltha.Device)
734 logger.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
735 /*
736 // Update the all ports state on that device to disable
737 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
738 logger.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
739 return er
740 }
741
742 //Update the device oper state and connection status
743 cloned.OperStatus = voltha.OperStatus_UNKNOWN
744 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
745 dh.device = cloned
746
747 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
748 logger.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
749 return er
750 }
751
752 //get the child device for the parent device
753 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
754 if err != nil {
755 logger.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
756 return err
757 }
758 for _, onuDevice := range onuDevices.Items {
759
760 // Update onu state as down in onu adapter
761 onuInd := oop.OnuIndication{}
762 onuInd.OperState = "down"
763 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
764 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
765 if er != nil {
766 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
767 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
768 //Do not return here and continue to process other ONUs
769 }
770 }
771 // * Discovered ONUs entries need to be cleared , since after OLT
772 // is up, it starts sending discovery indications again* /
773 dh.discOnus = sync.Map{}
774 logger.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
775 return nil
776 */
777 err = errors.New("Device FSM: function not implemented yet!")
778 e.Cancel(err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000779 logger.Debug("doStateDown-done")
Matteo Scandolod132c0e2020-04-24 17:06:25 -0700780 return
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000781}
782
783// DeviceHandler StateMachine related state transition methods ##### end #########
784// #################################################################################
785
786// ###################################################
787// DeviceHandler utility methods ##### begin #########
788
mpagenko3af1f032020-06-10 08:53:41 +0000789//GetOnuDeviceEntry getsthe ONU device entry and may wait until its value is defined
790func (dh *DeviceHandler) GetOnuDeviceEntry(aWait bool) *OnuDeviceEntry {
791 dh.lockDevice.RLock()
792 pOnuDeviceEntry := dh.pOnuOmciDevice
793 if aWait && pOnuDeviceEntry == nil {
794 //keep the read sema short to allow for subsequent write
795 dh.lockDevice.RUnlock()
divyadesai4d299552020-08-18 07:13:49 +0000796 logger.Debugw("Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000797 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
798 // so it might be needed to wait here for that event with some timeout
799 select {
800 case <-time.After(60 * time.Second): //timer may be discussed ...
divyadesai4d299552020-08-18 07:13:49 +0000801 logger.Errorw("No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000802 return nil
803 case <-dh.deviceEntrySet:
divyadesai4d299552020-08-18 07:13:49 +0000804 logger.Debugw("devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000805 // if written now, we can return the written value without sema
806 return dh.pOnuOmciDevice
807 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000808 }
mpagenko3af1f032020-06-10 08:53:41 +0000809 dh.lockDevice.RUnlock()
810 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000811}
812
mpagenko3af1f032020-06-10 08:53:41 +0000813//SetOnuDeviceEntry sets the ONU device entry within the handler
mpagenkoaf801632020-07-03 10:00:42 +0000814func (dh *DeviceHandler) SetOnuDeviceEntry(
815 apDeviceEntry *OnuDeviceEntry, apOnuTp *OnuUniTechProf) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000816 dh.lockDevice.Lock()
817 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +0000818 dh.pOnuOmciDevice = apDeviceEntry
819 dh.pOnuTP = apOnuTp
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000820 return nil
821}
822
mpagenko3af1f032020-06-10 08:53:41 +0000823//AddOnuDeviceEntry creates a new ONU device or returns the existing
824func (dh *DeviceHandler) AddOnuDeviceEntry(ctx context.Context) error {
divyadesai4d299552020-08-18 07:13:49 +0000825 logger.Debugw("adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000826
mpagenko3af1f032020-06-10 08:53:41 +0000827 deviceEntry := dh.GetOnuDeviceEntry(false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000828 if deviceEntry == nil {
829 /* costum_me_map in python code seems always to be None,
830 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
831 /* also no 'clock' argument - usage open ...*/
832 /* and no alarm_db yet (oo.alarm_db) */
mpagenkoaf801632020-07-03 10:00:42 +0000833 deviceEntry = NewOnuDeviceEntry(ctx, dh.deviceID, dh.pOpenOnuAc.KVStoreHost,
834 dh.pOpenOnuAc.KVStorePort, dh.pOpenOnuAc.KVStoreType,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000835 dh, dh.coreProxy, dh.AdapterProxy,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000836 dh.pOpenOnuAc.pSupportedFsms) //nil as FSM pointer would yield deviceEntry internal defaults ...
mpagenkoaf801632020-07-03 10:00:42 +0000837 onuTechProfProc := NewOnuUniTechProf(ctx, dh.deviceID, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000838 //error treatment possible //TODO!!!
mpagenkoaf801632020-07-03 10:00:42 +0000839 dh.SetOnuDeviceEntry(deviceEntry, onuTechProfProc)
mpagenko3af1f032020-06-10 08:53:41 +0000840 // fire deviceEntry ready event to spread to possibly waiting processing
841 dh.deviceEntrySet <- true
divyadesai4d299552020-08-18 07:13:49 +0000842 logger.Infow("onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000843 } else {
divyadesai4d299552020-08-18 07:13:49 +0000844 logger.Infow("onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000845 }
846 // might be updated with some error handling !!!
847 return nil
848}
849
850// doStateInit provides the device update to the core
851func (dh *DeviceHandler) create_interface(onuind *oop.OnuIndication) error {
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000852 logger.Debugw("create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
853 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
854
855 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000856
mpagenko3af1f032020-06-10 08:53:41 +0000857 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
858 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000859 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000860 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000861 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
862 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
863 // 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 +0000864 // 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 +0000865 // so let's just try to keep it simple ...
866 /*
867 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
868 if err != nil || device == nil {
869 //TODO: needs to handle error scenarios
870 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
871 return errors.New("Voltha Device not found")
872 }
873 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000874
mpagenko3af1f032020-06-10 08:53:41 +0000875 pDevEntry := dh.GetOnuDeviceEntry(true)
876 if pDevEntry != nil {
877 pDevEntry.Start(context.TODO())
878 } else {
divyadesai4d299552020-08-18 07:13:49 +0000879 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +0000880 return errors.New("No valid OnuDevice")
881 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000882 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
divyadesai4d299552020-08-18 07:13:49 +0000883 logger.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000884 }
mpagenko3af1f032020-06-10 08:53:41 +0000885 dh.deviceReason = "starting-openomci"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000886
887 /* this might be a good time for Omci Verify message? */
888 verifyExec := make(chan bool)
889 omci_verify := NewOmciTestRequest(context.TODO(),
mpagenko3af1f032020-06-10 08:53:41 +0000890 dh.device.Id, pDevEntry.PDevOmciCC,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000891 true, true) //eclusive and allowFailure (anyway not yet checked)
892 omci_verify.PerformOmciTest(context.TODO(), verifyExec)
893
894 /* give the handler some time here to wait for the OMCi verification result
895 after Timeout start and try MibUpload FSM anyway
896 (to prevent stopping on just not supported OMCI verification from ONU) */
897 select {
898 case <-time.After(2 * time.Second):
899 logger.Warn("omci start-verification timed out (continue normal)")
900 case testresult := <-verifyExec:
901 logger.Infow("Omci start verification done", log.Fields{"result": testresult})
902 }
903
904 /* In py code it looks earlier (on activate ..)
905 # Code to Run OMCI Test Action
906 kwargs_omci_test_action = {
907 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
908 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
909 }
910 serial_number = device.serial_number
911 self._test_request = OmciTestRequest(self.core_proxy,
912 self.omci_agent, self.device_id,
913 AniG, serial_number,
914 self.logical_device_id,
915 exclusive=False,
916 **kwargs_omci_test_action)
917 ...
918 # Start test requests after a brief pause
919 if not self._test_request_started:
920 self._test_request_started = True
921 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
922 reactor.callLater(tststart, self._test_request.start_collector)
923
924 */
925 /* which is then: in omci_test_request.py : */
926 /*
927 def start_collector(self, callback=None):
928 """
929 Start the collection loop for an adapter if the frequency > 0
930
931 :param callback: (callable) Function to call to collect PM data
932 """
933 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
934 if callback is None:
935 callback = self.perform_test_omci
936
937 if self.lc is None:
938 self.lc = LoopingCall(callback)
939
940 if self.default_freq > 0:
941 self.lc.start(interval=self.default_freq / 10)
942
943 def perform_test_omci(self):
944 """
945 Perform the initial test request
946 """
947 ani_g_entities = self._device.configuration.ani_g_entities
948 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
949 is not None else None
950 self._entity_id = ani_g_entities_ids[0]
951 self.logger.info('perform-test', entity_class=self._entity_class,
952 entity_id=self._entity_id)
953 try:
954 frame = MEFrame(self._entity_class, self._entity_id, []).test()
955 result = yield self._device.omci_cc.send(frame)
956 if not result.fields['omci_message'].fields['success_code']:
957 self.logger.info('Self-Test Submitted Successfully',
958 code=result.fields[
959 'omci_message'].fields['success_code'])
960 else:
961 raise TestFailure('Test Failure: {}'.format(
962 result.fields['omci_message'].fields['success_code']))
963 except TimeoutError as e:
964 self.deferred.errback(failure.Failure(e))
965
966 except Exception as e:
967 self.logger.exception('perform-test-Error', e=e,
968 class_id=self._entity_class,
969 entity_id=self._entity_id)
970 self.deferred.errback(failure.Failure(e))
971
972 */
973
974 // PM related heartbeat??? !!!TODO....
975 //self._heartbeat.enabled = True
976
mpagenko1cc3cb42020-07-27 15:24:38 +0000977 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
978 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
979 * as further OltAdapter processing may rely on the deviceReason event 'MibUploadDone' as a result of the FSM processing
980 * otherwise some processing synchronisation would be required - cmp. e.g TechProfile processing
981 */
982 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +0000983 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000984 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +0000985 if pMibUlFsm.Is(ulStDisabled) {
986 if err := pMibUlFsm.Event(ulEvStart); err != nil {
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000987 logger.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"err": err})
988 return errors.New("Can't go to state starting")
989 } else {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000990 logger.Debugw("MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000991 //Determine ONU status and start/re-start MIB Synchronization tasks
992 //Determine if this ONU has ever synchronized
993 if true { //TODO: insert valid check
mpagenko1cc3cb42020-07-27 15:24:38 +0000994 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000995 logger.Errorw("MibSyncFsm: Can't go to state resetting_mib", log.Fields{"err": err})
996 return errors.New("Can't go to state resetting_mib")
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +0000997 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000998 } else {
mpagenko1cc3cb42020-07-27 15:24:38 +0000999 pMibUlFsm.Event(ulEvExamineMds)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001000 logger.Debugw("state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001001 //Examine the MIB Data Sync
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001002 // callbacks to be handled:
mpagenko1cc3cb42020-07-27 15:24:38 +00001003 // Event(ulEvSuccess)
1004 // Event(ulEvTimeout)
1005 // Event(ulEvMismatch)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001006 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001007 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001008 } else {
1009 logger.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current())})
1010 return errors.New("wrong state of MibSyncFsm")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001011 }
1012 } else {
divyadesai4d299552020-08-18 07:13:49 +00001013 logger.Errorw("MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001014 return errors.New("cannot execut MibSync")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001015 }
1016 return nil
1017}
1018
mpagenko3af1f032020-06-10 08:53:41 +00001019func (dh *DeviceHandler) updateInterface(onuind *oop.OnuIndication) error {
1020 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
1021 if dh.deviceReason != "stopping-openomci" {
divyadesai4d299552020-08-18 07:13:49 +00001022 logger.Debugw("updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001023 //stop all running SM processing - make use of the DH-state as mirrored in the deviceReason
1024 pDevEntry := dh.GetOnuDeviceEntry(false)
1025 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001026 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001027 return errors.New("No valid OnuDevice")
1028 }
1029
1030 switch dh.deviceReason {
1031 case "starting-openomci":
1032 { //MIBSync FSM may run
1033 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
1034 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001035 pMibUlFsm.Event(ulEvStop) //TODO!! verify if MibSyncFsm stop-processing is sufficient (to allow it again afterwards)
mpagenko3af1f032020-06-10 08:53:41 +00001036 }
1037 }
1038 case "discovery-mibsync-complete":
1039 { //MibDownload may run
1040 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1041 if pMibDlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001042 pMibDlFsm.Event(dlEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001043 }
1044 }
1045 default:
mpagenko3dbcdd22020-07-22 07:38:45 +00001046 {
1047 //port lock/unlock FSM's may be active
mpagenko3af1f032020-06-10 08:53:41 +00001048 if dh.pUnlockStateFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001049 dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001050 }
1051 if dh.pLockStateFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001052 dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
mpagenko3af1f032020-06-10 08:53:41 +00001053 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001054 //techProfile related PonAniConfigFsm FSM may be active
1055 // maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1056 if dh.pOnuTP.pAniConfigFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001057 dh.pOnuTP.pAniConfigFsm.pAdaptFsm.pFsm.Event(aniEvReset)
mpagenko3dbcdd22020-07-22 07:38:45 +00001058 }
mpagenko3af1f032020-06-10 08:53:41 +00001059 }
1060 //TODO!!! care about PM/Alarm processing once started
1061 }
1062 //TODO: from here the deviceHandler FSM itself may be stuck in some of the initial states
1063 // (mainly the still seperate 'Event states')
1064 // so it is questionable, how this is resolved after some possible re-enable
1065 // assumption there is obviously, that the system may continue with some 'after "mib-download-done" state'
1066
1067 //stop/remove(?) the device entry
1068 pDevEntry.Stop(context.TODO()) //maybe some more sophisticated context treatment should be used here?
1069
1070 //TODO!!! remove existing traffic profiles
1071 /* from py code, if TP's exist, remove them - not yet implemented
1072 self._tp = dict()
1073 # Let TP download happen again
1074 for uni_id in self._tp_service_specific_task:
1075 self._tp_service_specific_task[uni_id].clear()
1076 for uni_id in self._tech_profile_download_done:
1077 self._tech_profile_download_done[uni_id].clear()
1078 */
1079
1080 dh.disableUniPortStateUpdate()
1081
1082 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "stopping-openomci"); err != nil {
1083 logger.Errorw("error-DeviceReasonUpdate to 'stopping-openomci'",
divyadesai4d299552020-08-18 07:13:49 +00001084 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001085 // abort: system behavior is just unstable ...
1086 return err
1087 }
1088 dh.deviceReason = "stopping-openomci"
1089
1090 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1091 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
1092 logger.Errorw("error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001093 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001094 // abort: system behavior is just unstable ...
1095 return err
1096 }
1097 } else {
divyadesai4d299552020-08-18 07:13:49 +00001098 logger.Debugw("updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001099 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001100 return nil
1101}
1102
mpagenko3af1f032020-06-10 08:53:41 +00001103//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001104func (dh *DeviceHandler) DeviceProcStatusUpdate(dev_Event OnuDeviceEvent) {
1105 switch dev_Event {
1106 case MibDatabaseSync:
1107 {
divyadesai4d299552020-08-18 07:13:49 +00001108 logger.Debugw("MibInSync event received", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001109 //initiate DevStateUpdate
1110 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
1111 logger.Errorw("error-DeviceReasonUpdate to 'mibsync-complete'", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001112 "device-id": dh.deviceID, "error": err})
mpagenko3dbcdd22020-07-22 07:38:45 +00001113 } else {
divyadesai4d299552020-08-18 07:13:49 +00001114 logger.Infow("dev reason updated to 'MibSync complete'", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001115 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001116 //set internal state anyway - as it was done
mpagenko3af1f032020-06-10 08:53:41 +00001117 dh.deviceReason = "discovery-mibsync-complete"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001118
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001119 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001120 pDevEntry := dh.GetOnuDeviceEntry(false)
1121 if unigInstKeys := pDevEntry.pOnuDB.GetSortedInstKeys(me.UniGClassID); len(unigInstKeys) > 0 {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001122 for _, mgmtEntityId := range unigInstKeys {
1123 logger.Debugw("Add UNI port for stored UniG instance:", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001124 "device-id": dh.deviceID, "UnigMe EntityID": mgmtEntityId})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001125 dh.addUniPort(mgmtEntityId, i, UniPPTP)
1126 i++
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001127 }
1128 } else {
divyadesai4d299552020-08-18 07:13:49 +00001129 logger.Debugw("No UniG instances found", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001130 }
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001131 if veipInstKeys := pDevEntry.pOnuDB.GetSortedInstKeys(me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001132 for _, mgmtEntityId := range veipInstKeys {
1133 logger.Debugw("Add VEIP acc. to stored VEIP instance:", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001134 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityId})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001135 dh.addUniPort(mgmtEntityId, i, UniVEIP)
1136 i++
1137 }
1138 } else {
divyadesai4d299552020-08-18 07:13:49 +00001139 logger.Debugw("No VEIP instances found", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001140 }
1141 if i == 0 {
divyadesai4d299552020-08-18 07:13:49 +00001142 logger.Warnw("No PPTP instances found", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001143 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144
mpagenko3af1f032020-06-10 08:53:41 +00001145 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here
1146 * left the code here as comment in case such processing should prove needed unexpectedly
1147 // Init Uni Ports to Admin locked state
1148 // maybe not really needed here as UNI ports should be locked by default, but still left as available in python code
1149 // *** should generate UniLockStateDone event *****
1150 if dh.pLockStateFsm == nil {
1151 dh.createUniLockFsm(true, UniLockStateDone)
1152 } else { //LockStateFSM already init
1153 dh.pLockStateFsm.SetSuccessEvent(UniLockStateDone)
1154 dh.runUniLockFsm(true)
1155 }
1156 }
1157 case UniLockStateDone:
1158 {
divyadesai4d299552020-08-18 07:13:49 +00001159 logger.Infow("UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001160 * lockState processing commented out
1161 */
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001162 /* Mib download procedure -
1163 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1164 */
mpagenko3af1f032020-06-10 08:53:41 +00001165 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001166 if pMibDlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001167 if pMibDlFsm.Is(dlStDisabled) {
1168 if err := pMibDlFsm.Event(dlEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001169 logger.Errorw("MibDownloadFsm: Can't go to state starting", log.Fields{"err": err})
1170 // maybe try a FSM reset and then again ... - TODO!!!
1171 } else {
1172 logger.Debugw("MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1173 // maybe use more specific states here for the specific download steps ...
mpagenko1cc3cb42020-07-27 15:24:38 +00001174 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001175 logger.Errorw("MibDownloadFsm: Can't start CreateGal", log.Fields{"err": err})
1176 } else {
1177 logger.Debugw("state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
1178 //Begin MIB data download (running autonomously)
1179 }
1180 }
1181 } else {
1182 logger.Errorw("wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current())})
1183 // maybe try a FSM reset and then again ... - TODO!!!
1184 }
1185 /***** Mib download started */
1186 } else {
divyadesai4d299552020-08-18 07:13:49 +00001187 logger.Errorw("MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001188 }
1189 }
1190 case MibDownloadDone:
1191 {
divyadesai4d299552020-08-18 07:13:49 +00001192 logger.Debugw("MibDownloadDone event received", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001193 //initiate DevStateUpdate
1194 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID,
1195 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
divyadesai4d299552020-08-18 07:13:49 +00001196 logger.Errorw("error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3dbcdd22020-07-22 07:38:45 +00001197 } else {
divyadesai4d299552020-08-18 07:13:49 +00001198 logger.Debugw("dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001199 }
mpagenko3af1f032020-06-10 08:53:41 +00001200
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001201 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "initial-mib-downloaded"); err != nil {
1202 logger.Errorw("error-DeviceReasonUpdate to 'initial-mib-downloaded'",
divyadesai4d299552020-08-18 07:13:49 +00001203 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3dbcdd22020-07-22 07:38:45 +00001204 } else {
divyadesai4d299552020-08-18 07:13:49 +00001205 logger.Infow("dev reason updated to 'initial-mib-downloaded'", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001206 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001207 //set internal state anyway - as it was done
mpagenko3af1f032020-06-10 08:53:41 +00001208 dh.deviceReason = "initial-mib-downloaded"
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001209 // *** should generate UniUnlockStateDone event *****
1210 if dh.pUnlockStateFsm == nil {
1211 dh.createUniLockFsm(false, UniUnlockStateDone)
1212 } else { //UnlockStateFSM already init
1213 dh.pUnlockStateFsm.SetSuccessEvent(UniUnlockStateDone)
1214 dh.runUniLockFsm(false)
1215 }
1216 }
1217 case UniUnlockStateDone:
1218 {
mpagenko3af1f032020-06-10 08:53:41 +00001219 go dh.enableUniPortStateUpdate() //cmp python yield self.enable_ports()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001220
divyadesai4d299552020-08-18 07:13:49 +00001221 logger.Infow("UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001222 raisedTs := time.Now().UnixNano()
1223 go dh.sendOnuOperStateEvent(voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1224 }
mpagenko3dbcdd22020-07-22 07:38:45 +00001225 case OmciAniConfigDone:
1226 {
divyadesai4d299552020-08-18 07:13:49 +00001227 logger.Debugw("OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001228 //TODO!: it might be needed to check some 'cached' pending flow configuration (vlan setting)
1229 // - to consider with outstanding flow implementation
1230 // attention: the device reason update is done based on ONU-UNI-Port related activity
1231 // - which may cause some inconsistency
1232 if dh.deviceReason != "tech-profile-config-download-success" {
1233 // which may be the case from some previous actvity on another UNI Port of the ONU
1234 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "tech-profile-config-download-success"); err != nil {
1235 logger.Errorw("error-DeviceReasonUpdate to 'tech-profile-config-download-success'",
divyadesai4d299552020-08-18 07:13:49 +00001236 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3dbcdd22020-07-22 07:38:45 +00001237 } else {
1238 logger.Infow("update dev reason to 'tech-profile-config-download-success'",
divyadesai4d299552020-08-18 07:13:49 +00001239 log.Fields{"device-id": dh.deviceID})
mpagenko3dbcdd22020-07-22 07:38:45 +00001240 }
1241 //set internal state anyway - as it was done
1242 dh.deviceReason = "tech-profile-config-download-success"
1243 }
1244 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001245 default:
1246 {
divyadesai4d299552020-08-18 07:13:49 +00001247 logger.Warnw("unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": dev_Event})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001248 }
1249 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001250}
1251
Holger Hildebrandtdd23cc22020-05-19 13:32:18 +00001252func (dh *DeviceHandler) addUniPort(a_uniInstNo uint16, a_uniId uint8, a_portType UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001253 // parameters are IntfId, OnuId, uniId
1254 uniNo := MkUniPortNum(dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
1255 uint32(a_uniId))
1256 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001257 logger.Warnw("onuUniPort-add: Port already exists", log.Fields{"for InstanceId": a_uniInstNo})
1258 } else {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001259 //with arguments a_uniId, a_portNo, a_portType
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001260 pUniPort := NewOnuUniPort(a_uniId, uniNo, a_uniInstNo, a_portType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001261 if pUniPort == nil {
1262 logger.Warnw("onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": a_uniInstNo})
1263 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001264 //store UniPort with the System-PortNumber key
1265 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001266 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001267 if err := pUniPort.CreateVolthaPort(dh); err == nil {
1268 logger.Infow("onuUniPort-added", log.Fields{"for PortNo": uniNo})
1269 } //error logging already within UniPort method
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001270 }
1271 }
1272}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001273
mpagenko3af1f032020-06-10 08:53:41 +00001274// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
1275func (dh *DeviceHandler) enableUniPortStateUpdate() {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001276 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
1277 // but towards core only the first port active state is signalled
1278 // with following remark:
1279 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
1280 // # load on the core
1281
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001282 // lock_ports(false) as done in py code here is shifted to separate call from devicevent processing
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001283
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001284 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00001285 // only if this port is validated for operState transfer
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001286 if (1<<uniPort.uniId)&ActiveUniPortStateUpdateMask == (1 << uniPort.uniId) {
1287 logger.Infow("onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo})
1288 uniPort.SetOperState(vc.OperStatus_ACTIVE)
1289 //maybe also use getter functions on uniPort - perhaps later ...
mpagenko3af1f032020-06-10 08:53:41 +00001290 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
1291 }
1292 }
1293}
1294
1295// Disable UniPortState and update core port state accordingly
1296func (dh *DeviceHandler) disableUniPortStateUpdate() {
1297 // compare enableUniPortStateUpdate() above
1298 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
1299 for uniNo, uniPort := range dh.uniEntityMap {
1300 // only if this port is validated for operState transfer
1301 if (1<<uniPort.uniId)&ActiveUniPortStateUpdateMask == (1 << uniPort.uniId) {
1302 logger.Infow("onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo})
1303 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
1304 //maybe also use getter functions on uniPort - perhaps later ...
1305 go dh.coreProxy.PortStateUpdate(context.TODO(), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtbe674422020-05-05 13:05:30 +00001306 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001307 }
1308}
1309
1310// ONU_Active/Inactive announcement on system KAFKA bus
1311// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
1312func (dh *DeviceHandler) sendOnuOperStateEvent(a_OperState vc.OperStatus_Types, a_deviceID string, raisedTs int64) {
1313 var de voltha.DeviceEvent
1314 eventContext := make(map[string]string)
1315 //Populating event context
1316 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
1317 parentDevice, err := dh.coreProxy.GetDevice(context.TODO(), dh.parentId, dh.parentId)
1318 if err != nil || parentDevice == nil {
1319 logger.Errorw("Failed to fetch parent device for OnuEvent",
1320 log.Fields{"parentId": dh.parentId, "err": err})
1321 }
1322 oltSerialNumber := parentDevice.SerialNumber
1323
1324 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
1325 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
1326 eventContext["serial-number"] = dh.device.SerialNumber
1327 eventContext["olt_serial_number"] = oltSerialNumber
1328 eventContext["device_id"] = a_deviceID
1329 eventContext["registration_id"] = a_deviceID //py: string(device_id)??
1330 logger.Debugw("prepare ONU_ACTIVATED event",
1331 log.Fields{"DeviceId": a_deviceID, "EventContext": eventContext})
1332
1333 /* Populating device event body */
1334 de.Context = eventContext
1335 de.ResourceId = a_deviceID
1336 if a_OperState == voltha.OperStatus_ACTIVE {
1337 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
1338 de.Description = fmt.Sprintf("%s Event - %s - %s",
1339 cEventObjectType, cOnuActivatedEvent, "Raised")
1340 } else {
1341 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
1342 de.Description = fmt.Sprintf("%s Event - %s - %s",
1343 cEventObjectType, cOnuActivatedEvent, "Cleared")
1344 }
1345 /* Send event to KAFKA */
1346 if err := dh.EventProxy.SendDeviceEvent(&de, equipment, pon, raisedTs); err != nil {
1347 logger.Warnw("could not send ONU_ACTIVATED event",
divyadesai4d299552020-08-18 07:13:49 +00001348 log.Fields{"device-id": a_deviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001349 }
1350 logger.Debugw("ONU_ACTIVATED event sent to KAFKA",
divyadesai4d299552020-08-18 07:13:49 +00001351 log.Fields{"device-id": a_deviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001352}
1353
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001354// createUniLockFsm initialises and runs the UniLock FSM to transfer teh OMCi related commands for port lock/unlock
1355func (dh *DeviceHandler) createUniLockFsm(aAdminState bool, devEvent OnuDeviceEvent) {
1356 chLSFsm := make(chan Message, 2048)
1357 var sFsmName string
1358 if aAdminState == true {
divyadesai4d299552020-08-18 07:13:49 +00001359 logger.Infow("createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001360 sFsmName = "LockStateFSM"
1361 } else {
divyadesai4d299552020-08-18 07:13:49 +00001362 logger.Infow("createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001363 sFsmName = "UnLockStateFSM"
1364 }
mpagenko3af1f032020-06-10 08:53:41 +00001365
1366 pDevEntry := dh.GetOnuDeviceEntry(true)
1367 if pDevEntry == nil {
divyadesai4d299552020-08-18 07:13:49 +00001368 logger.Errorw("No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001369 return
1370 }
1371 pLSFsm := NewLockStateFsm(pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001372 sFsmName, dh.deviceID, chLSFsm)
1373 if pLSFsm != nil {
1374 if aAdminState == true {
1375 dh.pLockStateFsm = pLSFsm
1376 } else {
1377 dh.pUnlockStateFsm = pLSFsm
1378 }
1379 dh.runUniLockFsm(aAdminState)
1380 } else {
divyadesai4d299552020-08-18 07:13:49 +00001381 logger.Errorw("LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001382 }
1383}
1384
1385// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
1386func (dh *DeviceHandler) runUniLockFsm(aAdminState bool) {
1387 /* Uni Port lock/unlock procedure -
1388 ***** should run via 'adminDone' state and generate the argument requested event *****
1389 */
1390 var pLSStatemachine *fsm.FSM
1391 if aAdminState == true {
1392 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
1393 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1394 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001395 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
1396 dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001397 }
1398 } else {
1399 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
1400 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
1401 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00001402 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
1403 dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001404 }
1405 }
1406 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001407 if pLSStatemachine.Is(uniStDisabled) {
1408 if err := pLSStatemachine.Event(uniEvStart); err != nil {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001409 logger.Warnw("LockStateFSM: can't start", log.Fields{"err": err})
1410 // maybe try a FSM reset and then again ... - TODO!!!
1411 } else {
1412 /***** LockStateFSM started */
1413 logger.Debugw("LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001414 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001415 }
1416 } else {
1417 logger.Warnw("wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00001418 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001419 // maybe try a FSM reset and then again ... - TODO!!!
1420 }
1421 } else {
divyadesai4d299552020-08-18 07:13:49 +00001422 logger.Errorw("LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00001423 // maybe try a FSM reset and then again ... - TODO!!!
1424 }
1425}
1426
mpagenkoaf801632020-07-03 10:00:42 +00001427//SetBackend provides a DB backend for the specified path on the existing KV client
1428func (dh *DeviceHandler) SetBackend(aBasePathKvStore string) *db.Backend {
1429 addr := dh.pOpenOnuAc.KVStoreHost + ":" + strconv.Itoa(dh.pOpenOnuAc.KVStorePort)
1430 logger.Debugw("SetKVStoreBackend", log.Fields{"IpTarget": addr,
divyadesai4d299552020-08-18 07:13:49 +00001431 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00001432 kvbackend := &db.Backend{
1433 Client: dh.pOpenOnuAc.kvClient,
1434 StoreType: dh.pOpenOnuAc.KVStoreType,
1435 /* address config update acc. to [VOL-2736] */
1436 Address: addr,
1437 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
1438 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00001439
mpagenkoaf801632020-07-03 10:00:42 +00001440 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001441}