blob: c6e81ad7589118ae8b9a1138a88d46a48bca1e32 [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +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 adaptercoreont provides the utility for onu devices, flows and statistics
18package adaptercoreont
19
20import (
21 "context"
22 "encoding/hex"
23 "errors"
24 "fmt"
25 "sync"
26 "time"
27
28 "github.com/gogo/protobuf/proto"
29 "github.com/golang/protobuf/ptypes"
30 "github.com/opencord/voltha-lib-go/v3/pkg/adapters/adapterif"
31 "github.com/opencord/voltha-lib-go/v3/pkg/log"
32 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
33 oop "github.com/opencord/voltha-protos/v3/go/openolt"
34 "github.com/opencord/voltha-protos/v3/go/voltha"
35)
36
37/*
38// Constants for number of retries and for timeout
39const (
40 MaxRetry = 10
41 MaxTimeOutInMs = 500
42)
43*/
44
45//DeviceHandler will interact with the ONU ? device.
46type DeviceHandler struct {
47 deviceID string
48 DeviceType string
49 adminState string
50 device *voltha.Device
51 logicalDeviceID string
52 ProxyAddressID string
53 ProxyAddressType string
54
55 coreProxy adapterif.CoreProxy
56 AdapterProxy adapterif.AdapterProxy
57 EventProxy adapterif.EventProxy
58 openOnuAc *OpenONUAC
59 transitionMap *TransitionMap
60 omciAgent *OpenOMCIAgent
61 ponPort *voltha.Port
62 onuOmciDevice *OnuDeviceEntry
63 exitChannel chan int
64 lockDevice sync.RWMutex
65
66 //Client oop.OpenoltClient
67 //clientCon *grpc.ClientConn
68 //flowMgr *OpenOltFlowMgr
69 //eventMgr *OpenOltEventMgr
70 //resourceMgr *rsrcMgr.OpenOltResourceMgr
71
72 //discOnus sync.Map
73 //onus sync.Map
74 //portStats *OpenOltStatisticsMgr
75 //metrics *pmmetrics.PmMetrics
76 stopCollector chan bool
77 stopHeartbeatCheck chan bool
78 activePorts sync.Map
79}
80
81/*
82//OnuDevice represents ONU related info
83type OnuDevice struct {
84 deviceID string
85 deviceType string
86 serialNumber string
87 onuID uint32
88 intfID uint32
89 proxyDeviceID string
90 uniPorts map[uint32]struct{}
91}
92
93//NewOnuDevice creates a new Onu Device
94func NewOnuDevice(devID, deviceTp, serialNum string, onuID, intfID uint32, proxyDevID string) *OnuDevice {
95 var device OnuDevice
96 device.deviceID = devID
97 device.deviceType = deviceTp
98 device.serialNumber = serialNum
99 device.onuID = onuID
100 device.intfID = intfID
101 device.proxyDeviceID = proxyDevID
102 device.uniPorts = make(map[uint32]struct{})
103 return &device
104}
105*/
106
107//NewDeviceHandler creates a new device handler
108func NewDeviceHandler(cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep adapterif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *DeviceHandler {
109 var dh DeviceHandler
110 dh.coreProxy = cp
111 dh.AdapterProxy = ap
112 dh.EventProxy = ep
113 cloned := (proto.Clone(device)).(*voltha.Device)
114 dh.deviceID = cloned.Id
115 dh.DeviceType = cloned.Type
116 dh.adminState = "up"
117 dh.device = cloned
118 dh.openOnuAc = adapter
119 dh.transitionMap = nil
120 dh.exitChannel = make(chan int, 1)
121 dh.lockDevice = sync.RWMutex{}
122 dh.stopCollector = make(chan bool, 2)
123 dh.stopHeartbeatCheck = make(chan bool, 2)
124 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
125 dh.activePorts = sync.Map{}
126 //TODO initialize the support classes.
127 return &dh
128}
129
130// start save the device to the data model
131func (dh *DeviceHandler) Start(ctx context.Context) {
132 dh.lockDevice.Lock()
133 defer dh.lockDevice.Unlock()
134 log.Debugw("starting-device-handler", log.Fields{"device": dh.device, "deviceId": dh.deviceID})
135 // Add the initial device to the local model
136 log.Debug("device-handler-started")
137}
138
139// stop stops the device dh. Not much to do for now
140func (dh *DeviceHandler) stop(ctx context.Context) {
141 dh.lockDevice.Lock()
142 defer dh.lockDevice.Unlock()
143 log.Debug("stopping-device-agent")
144 dh.exitChannel <- 1
145 log.Debug("device-agent-stopped")
146}
147
148// ##########################################################################################
149// DeviceHandler methods that implement the adapters interface requests ##### begin #########
150
151//AdoptDevice adopts the OLT device
152func (dh *DeviceHandler) AdoptDevice(ctx context.Context, device *voltha.Device) {
153 log.Debugw("Adopt_device", log.Fields{"deviceID": device.Id, "Address": device.GetHostAndPort()})
154
155 if dh.transitionMap == nil {
156 dh.transitionMap = NewTransitionMap(dh)
157 dh.transitionMap.Handle(ctx, DeviceInit)
158 } else {
159 log.Debug("AdoptDevice: Agent/device init already done")
160 }
161
162 /*
163 // Now, set the initial PM configuration for that device
164 if err := dh.coreProxy.DevicePMConfigUpdate(nil, dh.metrics.ToPmConfigs()); err != nil {
165 log.Errorw("error-updating-PMs", log.Fields{"deviceId": device.Id, "error": err})
166 }
167
168 go startCollector(dh)
169 go startHeartbeatCheck(dh)
170 */
171}
172
173//ProcessInterAdapterMessage sends the proxied messages to the target device
174// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
175// is meant, and then send the unmarshalled omci message to this onu
176func (dh *DeviceHandler) ProcessInterAdapterMessage(msg *ic.InterAdapterMessage) error {
177 msgID := msg.Header.Id
178 msgType := msg.Header.Type
179 fromTopic := msg.Header.FromTopic
180 toTopic := msg.Header.ToTopic
181 toDeviceID := msg.Header.ToDeviceId
182 proxyDeviceID := msg.Header.ProxyDeviceId
183 log.Debugw("InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
184 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
185
186 switch msgType {
187 case ic.InterAdapterMessageType_OMCI_REQUEST:
188 {
189 /* TOBECHECKED: I assume, ONU Adapter receives the message hier already 'unmarshalled'? else: (howTo?)*/
190 msgBody := msg.GetBody()
191
192 omciMsg := &ic.InterAdapterOmciMessage{}
193 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
194 log.Warnw("cannot-unmarshal-omci-msg-body", log.Fields{"error": err})
195 return err
196 }
197
198 //assuming omci message content is hex coded!
199 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
200 log.Debugw("inter-adapter-recv-omci",
201 log.Fields{"RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
202 //receive_message(omci_msg.message)
203 return dh.onuOmciDevice.PDevOmciCC.ReceiveMessage(context.TODO(), omciMsg.Message)
204 }
205 case ic.InterAdapterMessageType_ONU_IND_REQUEST:
206 {
207 /* TOBECHECKED: I assume, ONU Adapter receives the message hier already 'unmarshalled'? else: see above omci block */
208 msgBody := msg.GetBody()
209
210 onu_indication := &oop.OnuIndication{}
211 if err := ptypes.UnmarshalAny(msgBody, onu_indication); err != nil {
212 log.Warnw("cannot-unmarshal-onu-indication-msg-body", log.Fields{"error": err})
213 return err
214 }
215
216 onu_operstate := onu_indication.GetOperState()
217 log.Debugw("inter-adapter-recv-onu-ind", log.Fields{"OnuId": onu_indication.GetOnuId(),
218 "AdminState": onu_indication.GetAdminState(), "OperState": onu_operstate,
219 "SNR": onu_indication.GetSerialNumber()})
220
221 //interface related functioons might be error checked ....
222 if onu_operstate == "up" {
223 dh.create_interface(onu_indication)
224 } else if (onu_operstate == "down") || (onu_operstate == "unreachable") {
225 dh.update_interface(onu_indication)
226 } else {
227 log.Errorw("unknown-onu-indication operState", log.Fields{"OnuId": onu_indication.GetOnuId()})
228 return errors.New("InvalidOperState")
229 }
230 }
231 default:
232 {
233 log.Errorw("inter-adapter-unhandled-type", log.Fields{"msgType": msg.Header.Type})
234 return errors.New("unimplemented")
235 }
236 }
237
238 /* form py code:
239 elif request.header.type == InterAdapterMessageType.TECH_PROFILE_DOWNLOAD_REQUEST:
240 tech_msg = InterAdapterTechProfileDownloadMessage()
241 request.body.Unpack(tech_msg)
242 self.log.debug('inter-adapter-recv-tech-profile', tech_msg=tech_msg)
243
244 self.load_and_configure_tech_profile(tech_msg.uni_id, tech_msg.path)
245
246 elif request.header.type == InterAdapterMessageType.DELETE_GEM_PORT_REQUEST:
247 del_gem_msg = InterAdapterDeleteGemPortMessage()
248 request.body.Unpack(del_gem_msg)
249 self.log.debug('inter-adapter-recv-del-gem', gem_del_msg=del_gem_msg)
250
251 self.delete_tech_profile(uni_id=del_gem_msg.uni_id,
252 gem_port_id=del_gem_msg.gem_port_id,
253 tp_path=del_gem_msg.tp_path)
254
255 elif request.header.type == InterAdapterMessageType.DELETE_TCONT_REQUEST:
256 del_tcont_msg = InterAdapterDeleteTcontMessage()
257 request.body.Unpack(del_tcont_msg)
258 self.log.debug('inter-adapter-recv-del-tcont', del_tcont_msg=del_tcont_msg)
259
260 self.delete_tech_profile(uni_id=del_tcont_msg.uni_id,
261 alloc_id=del_tcont_msg.alloc_id,
262 tp_path=del_tcont_msg.tp_path)
263 else:
264 self.log.error("inter-adapter-unhandled-type", request=request)
265 */
266 return nil
267}
268
269// DeviceHandler methods that implement the adapters interface requests## end #########
270// #####################################################################################
271
272// ################ to be updated acc. needs of ONU Device ########################
273// DeviceHandler StateMachine related state transition methods ##### begin #########
274
275// doStateInit provides the device update to the core
276func (dh *DeviceHandler) doStateInit(ctx context.Context) error {
277 log.Debug("doStateInit-started")
278 /*
279 var err error
280 dh.clientCon, err = grpc.Dial(dh.device.GetHostAndPort(), grpc.WithInsecure(), grpc.WithBlock())
281 if err != nil {
282 log.Errorw("Failed to dial device", log.Fields{"DeviceId": dh.deviceID, "HostAndPort": dh.device.GetHostAndPort(), "err": err})
283 return err
284 }
285 return nil
286 */
287 // populate what we know. rest comes later after mib sync
288 dh.device.Root = false
289 dh.device.Vendor = "OpenONU"
290 dh.device.Model = "go"
291 dh.device.Reason = "activating-onu"
292 dh.logicalDeviceID = dh.deviceID
293
294 dh.coreProxy.DeviceUpdate(ctx, dh.device)
295
296 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
297 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
298 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
299 log.Debugw("device-updated", log.Fields{"deviceID": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
300 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
301 "ParentId": dh.device.ParentId, "ParentPortNo": dh.device.ParentPortNo})
302
303 /*
304 self._pon = PonPort.create(self, self._pon_port_number)
305 self._pon.add_peer(self.parent_id, self._pon_port_number)
306 self.log.debug('adding-pon-port-to-agent',
307 type=self._pon.get_port().type,
308 admin_state=self._pon.get_port().admin_state,
309 oper_status=self._pon.get_port().oper_status,
310 )
311 */
312 log.Debug("adding-pon-port")
313 ponPortNo := uint32(1)
314 if dh.device.ParentPortNo != 0 {
315 ponPortNo = dh.device.ParentPortNo
316 }
317
318 ponPort := &voltha.Port{
319 PortNo: ponPortNo,
320 Label: fmt.Sprintf("pon-%d", ponPortNo),
321 Type: voltha.Port_PON_ONU,
322 OperStatus: voltha.OperStatus_ACTIVE,
323 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.device.ParentId, // Peer device is OLT
324 PortNo: dh.device.ParentPortNo}}, // Peer port is parent's port number
325 }
326 var err error
327 if err = dh.coreProxy.PortCreated(context.TODO(), dh.deviceID, ponPort); err != nil {
328 log.Fatalf("PortCreated-failed-%s", err)
329 }
330
331 log.Debug("doStateInit-done")
332 return nil
333}
334
335// postInit setups the DeviceEntry for the conerned device
336func (dh *DeviceHandler) postInit(ctx context.Context) error {
337 /*
338 dh.Client = oop.NewOpenoltClient(dh.clientCon)
339 dh.transitionMap.Handle(ctx, GrpcConnected)
340 return nil
341 */
342 //start the Agent object with no specific FSM setting
343 dh.omciAgent = NewOpenOMCIAgent(ctx, dh.coreProxy, dh.AdapterProxy)
344 dh.omciAgent.Start(ctx)
345 // might be updated with some error handling !!!
346 dh.onuOmciDevice, _ = dh.omciAgent.Add_device(ctx, dh.deviceID, dh)
347 //dh.transitionMap.Handle(ctx, GrpcConnected)
348
349 /*
350 ############################################################################
351 # Setup Alarm handler
352 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
353 device.serial_number)
354 ############################################################################
355 # Setup PM configuration for this device
356 # Pass in ONU specific options
357 kwargs = {
358 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
359 'heartbeat': self.heartbeat,
360 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
361 }
362 self.log.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
363 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
364 self.logical_device_id, device.serial_number,
365 grouped=True, freq_override=False, **kwargs)
366 pm_config = self._pm_metrics.make_proto()
367 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
368 self.log.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
369 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
370
371 # Note, ONU ID and UNI intf set in add_uni_port method
372 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
373 ani_ports=[self._pon])
374
375 # Code to Run OMCI Test Action
376 kwargs_omci_test_action = {
377 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
378 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
379 }
380 serial_number = device.serial_number
381 self._test_request = OmciTestRequest(self.core_proxy,
382 self.omci_agent, self.device_id,
383 AniG, serial_number,
384 self.logical_device_id,
385 exclusive=False,
386 **kwargs_omci_test_action)
387
388 self.enabled = True
389 else:
390 self.log.info('onu-already-activated')
391 */
392
393 return nil
394}
395
396// doStateUp handle the onu up indication and update to voltha core
397func (dh *DeviceHandler) doStateUp(ctx context.Context) error {
398 /*
399 // Synchronous call to update device state - this method is run in its own go routine
400 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
401 voltha.OperStatus_ACTIVE); err != nil {
402 log.Errorw("Failed to update device with OLT UP indication", log.Fields{"deviceID": dh.device.Id, "error": err})
403 return err
404 }
405 return nil
406 */
407 return errors.New("unimplemented")
408}
409
410// doStateDown handle the onu down indication
411func (dh *DeviceHandler) doStateDown(ctx context.Context) error {
412 dh.lockDevice.Lock()
413 defer dh.lockDevice.Unlock()
414 log.Debug("do-state-down-start")
415
416 device, err := dh.coreProxy.GetDevice(ctx, dh.device.Id, dh.device.Id)
417 if err != nil || device == nil {
418 /*TODO: needs to handle error scenarios */
419 log.Errorw("Failed to fetch device device", log.Fields{"err": err})
420 return errors.New("failed to fetch device device")
421 }
422
423 cloned := proto.Clone(device).(*voltha.Device)
424 log.Debugw("do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
425 /*
426 // Update the all ports state on that device to disable
427 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
428 log.Errorw("updating-ports-failed", log.Fields{"deviceID": device.Id, "error": er})
429 return er
430 }
431
432 //Update the device oper state and connection status
433 cloned.OperStatus = voltha.OperStatus_UNKNOWN
434 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
435 dh.device = cloned
436
437 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
438 log.Errorw("error-updating-device-state", log.Fields{"deviceID": device.Id, "error": er})
439 return er
440 }
441
442 //get the child device for the parent device
443 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
444 if err != nil {
445 log.Errorw("failed to get child devices information", log.Fields{"deviceID": dh.device.Id, "error": err})
446 return err
447 }
448 for _, onuDevice := range onuDevices.Items {
449
450 // Update onu state as down in onu adapter
451 onuInd := oop.OnuIndication{}
452 onuInd.OperState = "down"
453 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
454 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
455 if er != nil {
456 log.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
457 "From Adapter": "openolt", "DevieType": onuDevice.Type, "DeviceID": onuDevice.Id})
458 //Do not return here and continue to process other ONUs
459 }
460 }
461 // * Discovered ONUs entries need to be cleared , since after OLT
462 // is up, it starts sending discovery indications again* /
463 dh.discOnus = sync.Map{}
464 log.Debugw("do-state-down-end", log.Fields{"deviceID": device.Id})
465 return nil
466 */
467 return errors.New("unimplemented")
468}
469
470// doStateConnected get the device info and update to voltha core
471// for comparison of the original method (not that easy to uncomment): compare here:
472// voltha-openolt-adapter/adaptercore/device_handler.go
473// -> this one obviously initiates all communication interfaces of the device ...?
474func (dh *DeviceHandler) doStateConnected(ctx context.Context) error {
475 log.Debug("OLT device has been connected")
476 return errors.New("unimplemented")
477}
478
479// DeviceHandler StateMachine related state transition methods ##### end #########
480// #################################################################################
481
482// ###################################################
483// DeviceHandler utility methods ##### begin #########
484
485// doStateInit provides the device update to the core
486func (dh *DeviceHandler) create_interface(onuind *oop.OnuIndication) error {
487 log.Debug("create_interface-started - not yet fully implemented (only device state update)")
488
489 if err := dh.coreProxy.DeviceStateUpdate(context.TODO(), dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
490 log.Errorw("error-updating-device-state", log.Fields{"deviceID": dh.deviceID, "error": err})
491 }
492
493 device, err := dh.coreProxy.GetDevice(context.TODO(), dh.device.Id, dh.device.Id)
494 if err != nil || device == nil {
495 /*TODO: needs to handle error scenarios */
496 log.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
497 return errors.New("Voltha Device not found")
498 }
499
500 dh.onuOmciDevice.Start(context.TODO())
501 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "starting-openomci"); err != nil {
502 log.Errorw("error-DeviceReasonUpdate to starting-openomci", log.Fields{"deviceID": dh.deviceID, "error": err})
503 }
504
505 /* this might be a good time for Omci Verify message? */
506 verifyExec := make(chan bool)
507 omci_verify := NewOmciTestRequest(context.TODO(),
508 dh.device.Id, dh.onuOmciDevice.PDevOmciCC,
509 true, true) //eclusive and allowFailure (anyway not yet checked)
510 omci_verify.PerformOmciTest(context.TODO(), verifyExec)
511
512 /* give the handler some time here to wait for the OMCi verification result
513 after Timeout start and try MibUpload FSM anyway
514 (to prevent stopping on just not supported OMCI verification from ONU) */
515 select {
516 case <-time.After(2 * time.Second):
517 log.Warn("omci start-verification timed out (continue normal)")
518 case testresult := <-verifyExec:
519 log.Infow("Omci start verification done", log.Fields{"result": testresult})
520 }
521
522 /* In py code it looks earlier (on activate ..)
523 # Code to Run OMCI Test Action
524 kwargs_omci_test_action = {
525 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
526 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
527 }
528 serial_number = device.serial_number
529 self._test_request = OmciTestRequest(self.core_proxy,
530 self.omci_agent, self.device_id,
531 AniG, serial_number,
532 self.logical_device_id,
533 exclusive=False,
534 **kwargs_omci_test_action)
535 ...
536 # Start test requests after a brief pause
537 if not self._test_request_started:
538 self._test_request_started = True
539 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
540 reactor.callLater(tststart, self._test_request.start_collector)
541
542 */
543 /* which is then: in omci_test_request.py : */
544 /*
545 def start_collector(self, callback=None):
546 """
547 Start the collection loop for an adapter if the frequency > 0
548
549 :param callback: (callable) Function to call to collect PM data
550 """
551 self.log.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
552 if callback is None:
553 callback = self.perform_test_omci
554
555 if self.lc is None:
556 self.lc = LoopingCall(callback)
557
558 if self.default_freq > 0:
559 self.lc.start(interval=self.default_freq / 10)
560
561 def perform_test_omci(self):
562 """
563 Perform the initial test request
564 """
565 ani_g_entities = self._device.configuration.ani_g_entities
566 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
567 is not None else None
568 self._entity_id = ani_g_entities_ids[0]
569 self.log.info('perform-test', entity_class=self._entity_class,
570 entity_id=self._entity_id)
571 try:
572 frame = MEFrame(self._entity_class, self._entity_id, []).test()
573 result = yield self._device.omci_cc.send(frame)
574 if not result.fields['omci_message'].fields['success_code']:
575 self.log.info('Self-Test Submitted Successfully',
576 code=result.fields[
577 'omci_message'].fields['success_code'])
578 else:
579 raise TestFailure('Test Failure: {}'.format(
580 result.fields['omci_message'].fields['success_code']))
581 except TimeoutError as e:
582 self.deferred.errback(failure.Failure(e))
583
584 except Exception as e:
585 self.log.exception('perform-test-Error', e=e,
586 class_id=self._entity_class,
587 entity_id=self._entity_id)
588 self.deferred.errback(failure.Failure(e))
589
590 */
591
592 // PM related heartbeat??? !!!TODO....
593 //self._heartbeat.enabled = True
594
595 //example how to call FSM - transition up to state "uploading"
596 if dh.onuOmciDevice.MibSyncFsm.Is("disabled") {
597
598 if err := dh.onuOmciDevice.MibSyncFsm.Event("start"); err != nil {
599 log.Errorw("MibSyncFsm: Can't go to state starting", log.Fields{"err": err})
600 return errors.New("Can't go to state starting")
601 } else {
602 log.Debug("MibSyncFsm", log.Fields{"state": string(dh.onuOmciDevice.MibSyncFsm.Current())})
603 //Determine ONU status and start/re-start MIB Synchronization tasks
604 //Determine if this ONU has ever synchronized
605 if true { //TODO: insert valid check
606 if err := dh.onuOmciDevice.MibSyncFsm.Event("load_mib_template"); err != nil {
607 log.Errorw("MibSyncFsm: Can't go to state loading_mib_template", log.Fields{"err": err})
608 return errors.New("Can't go to state loading_mib_template")
609 } else {
610 log.Debug("MibSyncFsm", log.Fields{"state": string(dh.onuOmciDevice.MibSyncFsm.Current())})
611 //Find and load a mib template. If not found proceed with mib_upload
612 // callbacks to be handled:
613 // Event("success")
614 // Event("timeout")
615 //no mib template found
616 if true { //TODO: insert valid check
617 if err := dh.onuOmciDevice.MibSyncFsm.Event("upload_mib"); err != nil {
618 log.Errorw("MibSyncFsm: Can't go to state uploading", log.Fields{"err": err})
619 return errors.New("Can't go to state uploading")
620 } else {
621 log.Debug("state of MibSyncFsm", log.Fields{"state": string(dh.onuOmciDevice.MibSyncFsm.Current())})
622 //Begin full MIB data upload, starting with a MIB RESET
623 // callbacks to be handled:
624 // success: e.Event("success")
625 // failure: e.Event("timeout")
626 }
627 }
628 }
629 } else {
630 dh.onuOmciDevice.MibSyncFsm.Event("examine_mds")
631 log.Debug("state of MibSyncFsm", log.Fields{"state": string(dh.onuOmciDevice.MibSyncFsm.Current())})
632 //Examine the MIB Data Sync
633 // callbacks to be handled:
634 // Event("success")
635 // Event("timeout")
636 // Event("mismatch")
637 }
638 }
639 } else {
640 log.Errorw("wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(dh.onuOmciDevice.MibSyncFsm.Current())})
641 return errors.New("wrong state of MibSyncFsm")
642 }
643 return nil
644}
645
646func (dh *DeviceHandler) update_interface(onuind *oop.OnuIndication) error {
647 log.Debug("update_interface-started - not yet implemented")
648 return nil
649}
650
651func (dh *DeviceHandler) DeviceStateUpdate(dev_Event OnuDeviceEvent) {
652 if dev_Event == MibDatabaseSync {
653 log.Debug("MibInSync Event: update dev state to 'MibSync complete'")
654 //initiate DevStateUpdate
655 if err := dh.coreProxy.DeviceReasonUpdate(context.TODO(), dh.deviceID, "discovery-mibsync-complete"); err != nil {
656 log.Errorw("error-DeviceReasonUpdate to mibsync-complete", log.Fields{"deviceID": dh.deviceID, "error": err})
657 }
658 } else {
659 log.Warnw("unhandled-device-event", log.Fields{"event": dev_Event})
660 }
661}