Example #1
0
    def perform_get_mds(self):
        """
        Get the 'mib_data_sync' attribute of the ONU
        """
        self.log.info('perform-get-mds')

        try:
            device = self.omci_agent.get_device(self.device_id)

            #########################################
            # Request (MDS supplied value does not matter for a 'get' request)

            results = yield device.omci_cc.send(OntDataFrame(mib_data_sync=123).get())

            omci_msg = results.fields['omci_message'].fields
            status = omci_msg['success_code']
            self.log.debug('ont-data-mds', status=status)

            assert status == RC.Success, 'Unexpected Response Status: {}'.format(status)

            # Successful if here
            self.deferred.callback(omci_msg['data']['mib_data_sync'])

        except TimeoutError as e:
            self.log.warn('get-mds-timeout', e=e)
            self.deferred.errback(failure.Failure(e))

        except Exception as e:
            self.log.exception('get-mds', e=e)
            self.deferred.errback(failure.Failure(e))
Example #2
0
    def perform_test_omci(self):
        """
        Perform the initial test request
        """
        ani_g_entities = self._device.configuration.ani_g_entities
        ani_g_entities_ids = ani_g_entities.keys() if ani_g_entities \
                                                      is not None else None
        self._entity_id = ani_g_entities_ids[0]

        self.log.info('perform-test',
                      entity_class=self._entity_class,
                      entity_id=self._entity_id)
        try:
            frame = MEFrame(self._entity_class, self._entity_id, []).test()
            result = yield self._device.omci_cc.send(frame)
            if not result.fields['omci_message'].fields['success_code']:
                self.log.info(
                    'Self-Test Submitted Successfully',
                    code=result.fields['omci_message'].fields['success_code'])
            else:
                raise TestFailure('Test Failure: {}'.format(
                    result.fields['omci_message'].fields['success_code']))
        except TimeoutError as e:
            self.deferred.errback(failure.Failure(e))

        except Exception as e:
            self.log.exception('perform-test',
                               e=e,
                               class_id=self._entity_class,
                               entity_id=self._entity_id)
            self.deferred.errback(failure.Failure(e))
Example #3
0
    def perform_sync_time(self):
        """
        Sync the time
        """
        self.log.debug('perform-sync-time')

        try:
            device = self.omci_agent.get_device(self.device_id)

            #########################################
            # ONT-G (ME #256)
            dt = datetime.utcnow() if self._use_utc else datetime.now()

            results = yield device.omci_cc.send(OntGFrame().synchronize_time(dt))

            omci_msg = results.fields['omci_message'].fields
            status = omci_msg['success_code']
            self.log.debug('sync-time', status=status)

            if status == RC.Success:
                self.log.info('sync-time', success_info=omci_msg['success_info'] & 0x0f)

            assert status == RC.Success, 'Unexpected Response Status: {}'.format(status)

            # Successful if here
            self.deferred.callback(results)

        except TimeoutError as e:
            self.log.warn('sync-time-timeout', e=e)
            self.deferred.errback(failure.Failure(e))

        except Exception as e:
            self.log.exception('sync-time', e=e)
            self.deferred.errback(failure.Failure(e))
Example #4
0
    def perform_alarm_resync(self):
        """
        Perform the ALARM Resynchronization sequence

        The sequence to be performed is:
            - get a copy of the current ALARM database

            - perform ALARM upload commands to get ONU's database and save this
              to a local DB.
        During the alarm upload process, the maximum time between alarm upload next
        requests is 1 minute.
        """
        self.log.info('perform-alarm-resync')

        try:
            command_sequence_number = yield self.snapshot_alarm()

            # Start the ALARM upload sequence, save alarms to the table
            commands_retrieved, alarm_table = yield self.upload_alarm(
                command_sequence_number)

            if commands_retrieved < command_sequence_number:
                e = AlarmDownloadException(
                    'Only retrieved {} of {} instances'.format(
                        commands_retrieved, command_sequence_number))
                self.deferred.errback(failure.Failure(e))

            self.deferred.callback({
                'commands_retrieved': commands_retrieved,
                'alarm_table': alarm_table
            })

        except Exception as e:
            self.log.exception('resync', e=e)
            self.deferred.errback(failure.Failure(e))
Example #5
0
    def perform_mib_resync(self):
        """
        Perform the MIB Resynchronization sequence

        The sequence to be performed are:
            - get a copy of the current MIB database (db_copy)

            - perform MIB upload commands to get ONU's database and save this
              to a local DB (db_active). Note that the ONU can still receive
              create/delete/set/get operations from the operator and source
              AVC notifications as well during this period.

            - Compare the information in the db_copy to the db_active

        During the mib upload process, the maximum time between mib upload next
        requests is 1 minute.
        """
        self.log.info('perform-mib-resync')

        # Try at least 3 times to snapshot the current MIB and get the
        # MIB upload request out so ONU snapshots its database

        db_copy = None
        number_of_commands = None
        commands_retrieved = 0

        try:
            results = yield self.snapshot_mib()
            db_copy = results[0]
            number_of_commands = results[1]

            # Start the MIB upload sequence
            commands_retrieved = yield self.upload_mib(number_of_commands)

        except Exception as e:
            self.deferred.errback(failure.Failure(e))
            returnValue(None)

        if db_copy is None:
            e = MibCopyException('Failed to get local database copy')
            self.deferred.errback(failure.Failure(e))
            returnValue('FAILED')

        if commands_retrieved < number_of_commands:
            e = MibDownloadException('Only retrieved {} of {} instances'.
                                     format(commands_retrieved, number_of_commands))
            self.deferred.errback(failure.Failure(e))
            returnValue('FAILED')

        # Compare the database

        mib_differences = self.compare_mibs(db_copy,
                                            self._db_active.query(self.device_id))

        if mib_differences is None:
            self.deferred.callback('success')
            self.deferred.callback('TODO: This task has not been coded.')

        # TODO: Handle mismatches
        pass
Example #6
0
    def send(self, frame, timeout=DEFAULT_OMCI_TIMEOUT, retry=0, high_priority=False):
        """
        Queue the OMCI Frame for a transmit to the ONU via the proxy_channel

        :param frame: (OMCIFrame) Message to send
        :param timeout: (int) Rx Timeout. 0=No response needed
        :param retry: (int) Additional retry attempts on channel failure, default=0
        :param high_priority: (bool) High Priority requests
        :return: (deferred) A deferred that fires when the response frame is received
                            or if an error/timeout occurs
        """
        if not self.enabled or self._proxy_address is None:
            # TODO custom exceptions throughout this code would be helpful
            self._tx_errors += 1
            return fail(result=failure.Failure(Exception('OMCI is not enabled')))

        timeout = float(timeout)
        if timeout > float(MAX_OMCI_REQUEST_AGE):
            self._tx_errors += 1
            msg = 'Maximum timeout is {} seconds'.format(MAX_OMCI_REQUEST_AGE)
            return fail(result=failure.Failure(Exception(msg)))

        if not isinstance(frame, OmciFrame):
            self._tx_errors += 1
            msg = "Invalid frame class '{}'".format(type(frame))
            return fail(result=failure.Failure(Exception(msg)))
        try:
            index = self._get_priority_index(high_priority)
            tx_tid = frame.fields['transaction_id']

            if tx_tid is None:
                tx_tid = self._get_tx_tid(high_priority=high_priority)
                frame.fields['transaction_id'] = tx_tid

            assert tx_tid not in self._pending[index], 'TX TID {} is already exists'.format(tx_tid)
            assert tx_tid > 0, 'Invalid Tx TID: {}'.format(tx_tid)

            # Queue it and request next Tx if tx channel is free
            d = defer.Deferred()

            self._queue_frame(d, frame, timeout, retry, high_priority, front=False)
            self._send_next_request(high_priority)

            if timeout == 0:
                self.log.debug("send-timeout-zero", tx_tid=tx_tid)
                self.reactor.callLater(0, d.callback, 'queued')

            return d

        except Exception as e:
            self._tx_errors += 1
            self._consecutive_errors += 1

            if self._consecutive_errors == 1:
                self.reactor.callLater(0, self._publish_connectivity_event, False)

            self.log.exception('send-omci', e=e)
            return fail(result=failure.Failure(e))
Example #7
0
    def perform_mib_reconcile(self):
        """
        Perform the MIB Reconciliation sequence.

        The sequence to reconcile will be to clean up ONU only MEs, followed by
        OLT/OpenOMCI-only MEs, and then finally correct common MEs with differing
        attributes.
        """
        self.log.debug('perform-mib-reconcile')

        try:
            successes = 0
            failures = 0

            if self._diffs['onu-only'] is not None and len(self._diffs['onu-only']):
                results = yield self.fix_onu_only(self._diffs['onu-only'],
                                                  self._diffs['onu-db'])
                self.log.debug('onu-only-results', good=results[0], bad=results[1])
                successes += results[0]
                failures += results[1]

            if self._diffs['olt-only'] is not None and len(self._diffs['olt-only']):
                results = yield self.fix_olt_only(self._diffs['olt-only'],
                                                  self._diffs['onu-db'],
                                                  self._diffs['olt-db'])
                self.log.debug('olt-only-results', good=results[0], bad=results[1])
                successes += results[0]
                failures += results[1]

            if self._diffs['attributes'] is not None and len(self._diffs['attributes']):
                results = yield self.fix_attributes_only(self._diffs['attributes'],
                                                         self._diffs['onu-db'],
                                                         self._diffs['olt-db'])
                self.log.debug('attributes-results', good=results[0], bad=results[1])
                successes += results[0]
                failures += results[1]

            # Success? Update MIB-data-sync
            if failures == 0:
                results = yield self.update_mib_data_sync()
                successes += results[0]
                failures += results[1]

            # Send back final status
            if failures > 0:
                msg = '{} Successful updates, {} failures'.format(successes, failure)
                error = MibPartialSuccessException(msg) if successes \
                    else MibReconcileException(msg)
                self.deferred.errback(failure.Failure(error))
            else:
                self.deferred.callback('{} Successful updates'.format(successes))

        except Exception as e:
            if not self.deferred.called:
                self.log.exception('reconcile', e=e)
                self.deferred.errback(failure.Failure(e))
Example #8
0
    def perform_mib_resync(self):
        """
        Perform the MIB Resynchronization sequence

        The sequence to be performed is:
            - get a copy of the current MIB database (db_copy)

            - perform MIB upload commands to get ONU's database and save this
              to a local DB (db_active). Note that the ONU can still receive
              create/delete/set/get operations from the operator and source
              AVC notifications as well during this period.

            - Compare the information in the db_copy to the db_active

        During the mib upload process, the maximum time between mib upload next
        requests is 1 minute.
        """
        self.log.info('perform-mib-resync')

        try:
            results = yield self.snapshot_mib()
            db_copy = results[0]

            if db_copy is None:
                e = MibCopyException('Failed to get local database copy')
                self.deferred.errback(failure.Failure(e))

            else:
                number_of_commands = results[1]

                # Start the MIB upload sequence
                commands_retrieved = yield self.upload_mib(number_of_commands)

                if commands_retrieved < number_of_commands:
                    e = MibDownloadException(
                        'Only retrieved {} of {} instances'.format(
                            commands_retrieved, number_of_commands))
                    self.deferred.errback(failure.Failure(e))
                else:
                    # Compare the databases
                    on_olt_only, on_onu_only, attr_diffs = \
                        self.compare_mibs(db_copy, self._db_active.query(self.device_id))

                    self.deferred.callback({
                        'on-olt-only':
                        on_olt_only if len(on_olt_only) else None,
                        'on-onu-only':
                        on_onu_only if len(on_onu_only) else None,
                        'attr-diffs':
                        attr_diffs if len(attr_diffs) else None
                    })

        except Exception as e:
            self.log.exception('resync', e=e)
            self.deferred.errback(failure.Failure(e))
Example #9
0
    def send(self, frame, timeout=DEFAULT_OMCI_TIMEOUT):
        """
        Send the OMCI Frame to the ONU via the proxy_channel

        :param frame: (OMCIFrame) Message to send
        :param timeout: (int) Rx Timeout. 0=Forever
        :return: (deferred) A deferred that fires when the response frame is received
                            or if an error/timeout occurs
        """
        self.flush(max_age=MAX_OMCI_REQUEST_AGE)

        assert timeout <= MAX_OMCI_REQUEST_AGE, \
            'Maximum timeout is {} seconds'.format(MAX_OMCI_REQUEST_AGE)
        assert isinstance(frame, OmciFrame), \
            "Invalid frame class '{}'".format(type(frame))

        if not self.enabled or self._proxy_address is None:
            # TODO custom exceptions throughout this code would be helpful
            return fail(
                result=failure.Failure(Exception('OMCI is not enabled')))

        try:
            tx_tid = frame.fields['transaction_id']
            if tx_tid is None:
                tx_tid = self._get_tx_tid()
                frame.fields['transaction_id'] = tx_tid

            assert tx_tid not in self._requests, 'TX TID {} is already exists'.format(
                tx_tid)
            assert tx_tid >= 0, 'Invalid Tx TID: {}'.format(tx_tid)

            ts = arrow.utcnow().float_timestamp
            d = defer.Deferred()

            self._adapter_agent.send_proxied_message(self._proxy_address,
                                                     hexify(str(frame)))
            self._tx_frames += 1
            self._requests[tx_tid] = (ts, d, frame, timeout)

            d.addCallbacks(self._request_success,
                           self._request_failure,
                           errbackArgs=(tx_tid, ))

            if timeout > 0:
                d.addTimeout(timeout, reactor)

        except Exception as e:
            self._tx_errors += 1
            self._consecutive_errors += 1
            self.log.exception('send-omci', e=e)
            return fail(result=failure.Failure(e))

        return d
Example #10
0
    def perform_alarm_sync_data(self):
        """
        Sync the time
        """
        self.log.info('perform-alarm-sync-data')

        try:
            device = self.omci_agent.get_device(self.device_id)

            #########################################
            # ONU Data (ME #2)
            # alarm_retrieval_mode=1, time=DEFAULT_OMCI_TIMEOUT
            results = yield device.omci_cc.send_get_all_alarm(alarm_retrieval_mode=1)
            self.stop_if_not_running()
            command_sequence_number = results.fields['omci_message'].fields['number_of_commands']

            for seq_no in xrange(command_sequence_number):
                if not device.active or not device.omci_cc.enabled:
                    raise AlarmSyncDataFailure('OMCI and/or ONU is not active')

                for retry in range(0, 3):
                    try:
                        self.log.debug('alarm-data-next-request', seq_no=seq_no,
                                       retry=retry,
                                       command_sequence_number=command_sequence_number)
                        yield device.omci_cc.send_get_all_alarm_next(seq_no)
                        self.stop_if_not_running()
                        self.log.debug('alarm-data-next-success', seq_no=seq_no,
                                       command_sequence_number=command_sequence_number)
                        break

                    except TimeoutError as e:
                        from common.utils.asleep import asleep
                        self.log.warn('alarm-data-timeout', e=e, seq_no=seq_no,
                                      command_sequence_number=command_sequence_number)
                        if retry >= 2:
                            raise AlarmSyncDataFailure('Alarm timeout failure on req {} of {}'.
                                                       format(seq_no + 1, command_sequence_number))
                        yield asleep(0.3)
                        self.stop_if_not_running()

            # Successful if here
            self.log.info('alarm-synchronized')
            self.deferred.callback(command_sequence_number)

        except TimeoutError as e:
            self.log.warn('alarm-sync-time-timeout', e=e)
            self.deferred.errback(failure.Failure(e))

        except Exception as e:
            self.log.exception('alarm-sync-time', e=e)
            self.deferred.errback(failure.Failure(e))
    def delete_tcont_and_associated_me(self):
        self.log.info('deleting-tcont')

        omci_cc = self._onu_device.omci_cc

        try:
            ################################################################################
            # Reset TCONT ME
            ################################################################################

            tcont_idents = self._onu_device.query_mib(Tcont.class_id)
            self.log.debug('tcont-idents', tcont_idents=tcont_idents)
            tcont_entity_id = None
            for k, v in tcont_idents.items():
                if not isinstance(v, dict):
                    continue
                alloc_check = v.get('attributes', {}).get('alloc_id', 0)
                # Some onu report both to indicate an available tcont
                if alloc_check == self._alloc_id:
                    tcont_entity_id = k
                    break

            if tcont_entity_id is None:
                self.log.error("tcont-not-found-for-delete",
                               alloc_id=self._alloc_id)
                return

            self.log.debug('found-tcont',
                           tcont_entity_id=tcont_entity_id,
                           alloc_id=self._alloc_id)

            # Remove the TCONT (rather reset the TCONT to point alloc_id to 0xffff)
            # The _tcont.remove_from_hardware is already doing check_status_and_state
            yield self._tcont.remove_from_hardware(omci_cc)

            # At this point, the gem-ports should have been removed already.
            # Remove the 8021p Mapper and ANI MacBridgePortConfigData
            yield self._delete__8021p_mapper__ani_mac_bridge_port()

            # There are no other associated MEs now.
            # There might be TrafficScheduler MEs that point to a TCONT.
            # TrafficScheduler ME not used currently.

            self.deferred.callback("tech-profile-remove-success--tcont")

        except TimeoutError as e:
            self.log.warn('rx-timeout-tech-profile', e=e)
            self.deferred.errback(failure.Failure(e))

        except Exception as e:
            self.log.exception('omci-delete-tech-profile', e=e)
            self.deferred.errback(failure.Failure(e))
Example #12
0
 def _connectedEb(self, f):
     if f.check(errors.ConnectionFailedError):
         # switch the failure and return an UNKNOWN status
         msg = "Unable to connect to manager."
         f = failure.Failure(util.NagiosUnknown(msg))
         util.unknown(msg)
     if f.check(errors.ConnectionRefusedError):
         # switch the failure and return a CRITICAL status
         msg = "Manager refused connection."
         f = failure.Failure(util.NagiosCritical(msg))
         util.critical(msg)
     # all other failures get forwarded to the managerDeferred errback as-is
     self.managerDeferred.errback(f)
    def perform_mib_download(self):
        """
        Send the commands to minimally configure the PON, Bridge, and
        UNI ports for this device. The application of any service flows
        and other characteristics are done as needed.
        """
        try:
            self.log.debug('function-entry')
            self.log.info('perform-download')

            device = self._handler.adapter_agent.get_device(self.device_id)

            if self._handler.enabled and len(self._handler.uni_ports) > 0:
                device.reason = 'performing-initial-mib-download'
                self._handler.adapter_agent.update_device(device)

            try:
                # Lock the UNI ports to prevent any alarms during initial configuration
                # of the ONU
                self.strobe_watchdog()

                # Provision the initial bridge configuration
                yield self.perform_initial_bridge_setup()

                for uni_port in self._handler.uni_ports:
                    yield self.enable_uni(uni_port, True)

                    # Provision the initial bridge configuration
                    yield self.perform_uni_initial_bridge_setup(uni_port)

                    # And re-enable the UNIs if needed
                    yield self.enable_uni(uni_port, False)

                self.deferred.callback('initial-download-success')

            except TimeoutError as e:
                self.log.error('initial-download-failure', e=e)
                self.deferred.errback(failure.Failure(e))

            except Exception as e:
                self.log.exception('initial-download-failure', e=e)
                self.deferred.errback(failure.Failure(e))

            else:
                e = MibResourcesFailure('Required resources are not available',
                                        len(self._handler.uni_ports))
                self.deferred.errback(failure.Failure(e))
        except BaseException as e:
            self.log.debug('@thyy_mib_check:', exception=e)
Example #14
0
    def perform_mib_download(self):
        """
        Send the commands to minimally configure the PON, Bridge, and
        UNI ports for this device. The application of any service flows
        and other characteristics are done as needed.
        """
        self.log.info('perform-download')

        device = self._handler.adapter_agent.get_device(self.device_id)

        def resources_available():
            return (device.vlan > 0 and
                    len(self._handler.uni_ports) > 0 and
                    len(self._handler.pon_port.tconts) and
                    len(self._handler.pon_port.gem_ports))

        if self._handler.enabled and resources_available():
            device.reason = 'Performing OMCI Download'
            self._handler.adapter_agent.update_device(device)

            try:
                # Lock the UNI ports to prevent any alarms during initial configuration
                # of the ONU
                self.strobe_watchdog()
                yield self.enable_unis(self._handler.uni_ports, True)

                # Provision the initial bridge configuration
                yield self.perform_initial_bridge_setup()

                # And not all the service specific work
                yield self.perform_service_specific_steps()

                # And re-enable the UNIs if needed
                yield self.enable_unis(self._handler.uni_ports, False)

                # If here, we are done
                device = self._handler.adapter_agent.get_device(self.device_id)

                device.reason = ''
                self._handler.adapter_agent.update_device(device)
                self.deferred.callback('TODO: What should we return to the caller?')

            except TimeoutError as e:
                self.deferred.errback(failure.Failure(e))

        else:
            # TODO: Provide better error reason, what was missing...
            e = MibResourcesFailure('Required resources are not available')
            self.deferred.errback(failure.Failure(e))
Example #15
0
    def perform_task(self):
        """
        Get the 'mib_data_sync' attribute of the ONU
        """
        try:
            if self._delay > 0:
                yield asleep(self._delay)

            if self._success:
                self.deferred.callback(self._value)

            self.deferred.errback(failure.Failure(self._value))

        except Exception as e:
            self.deferred.errback(failure.Failure(e))
Example #16
0
    def perform_get_capabilities(self):
        """
        Perform the MIB Capabilities sequence.

        The sequence is to perform a Get request with the attribute mask equal
        to 'me_type_table'.  The response to this request will carry the size
        of (number of get-next sequences).

        Then a loop is entered and get-next commands are sent for each sequence
        requested.
        """
        self.log.info('perform-get')

        try:
            self.strobe_watchdog()
            self._supported_entities = yield self.get_supported_entities()

            self.strobe_watchdog()
            self._supported_msg_types = yield self.get_supported_message_types(
            )

            self.log.debug('get-success',
                           supported_entities=self.supported_managed_entities,
                           supported_msg_types=self.supported_message_types)
            results = {
                'supported-managed-entities': self.supported_managed_entities,
                'supported-message-types': self.supported_message_types
            }
            self.deferred.callback(results)

        except Exception as e:
            self.log.exception('perform-get', e=e)
            self.deferred.errback(failure.Failure(e))
Example #17
0
    def perform_multicast(self):
        self.log.debug('performing-multicast',
                       device_id=self._device._device_id,
                       uni_id=self._uni_port.uni_id,
                       vlan_id=self._set_vlan_id,
                       multicast_gem_id=self._mcast_gem_id)

        try:
            # create gem port and use tcont
            yield self._create_gem_ports()

            # create multicast operation profile
            yield self._create_mcast_operation_profile()

            # set multicast operation profile
            yield self._set_mcast_operation_profile()

            # create multicast subscriber config data
            yield self._create_mcast_subscriber_conf_info()

            # create mac bridge port configuration data
            yield self._create_mac_bridge_configuration_data()

            # create vlan filtering entity
            yield self._create_vlan_tagging_filter_data()

            # set vlan filtering entity
            yield self._set_vlan_tagging_filter_data()

            self.deferred.callback(self)
        except Exception as e:
            self.log.exception('multicast exception', e=e)
            self.deferred.errback(failure.Failure(e))
    def perform_get_capabilities(self):
        """
        Perform the MIB Capabilities sequence.

        The sequence is to perform a Get request with the attribute mask equal
        to 'me_type_table'.  The response to this request will carry the size
        of (number of get-next sequences).

        Then a loop is entered and get-next commands are sent for each sequence
        requested.
        """
        self.log.info('perform-get')

        if self._omci_managed:
            # Return generator deferred/results
            return super(AdtnCapabilitiesTask, self).perform_get_capabilities()

        # Fixed values, no need to query
        try:
            self._supported_entities = self.supported_managed_entities
            self._supported_msg_types = self.supported_message_types

            self.log.debug('get-success',
                           supported_entities=self.supported_managed_entities,
                           supported_msg_types=self.supported_message_types)
            results = {
                'supported-managed-entities': self.supported_managed_entities,
                'supported-message-types': self.supported_message_types
            }
            self.deferred.callback(results)

        except Exception as e:
            self.log.exception('get-failed', e=e)
            self.deferred.errback(failure.Failure(e))
Example #19
0
 def perform_vlan_tagging(self):
     """
     Perform the vlan tagging
     """
     self.log.debug('vlan-filter-tagging-task',
                    uni_port=self._uni_port,
                    set_vlan_id=self._set_vlan_id,
                    set_vlan_pcp=self._set_vlan_pcp,
                    match_vlan=self._match_vlan,
                    tp_id=self._tp_id,
                    add_tag=self._add_tag)
     try:
         if self._add_tag:
             if not self._onu_handler.args.accept_incremental_evto_update:
                 yield self._bulk_update_evto_and_vlan_tag_filter()
             else:
                 yield self._incremental_update_evto_and_vlan_tag_filter()
         else:  # addTag = False
             if self._onu_handler.args.accept_incremental_evto_update:
                 self.log.info('removing-vlan-tagging')
                 yield self._delete_service_flow()
                 yield self._delete_vlan_filter_entity()
             else:
                 # Will be reset anyway on new vlan tagging operation
                 self.log.info("not-removing-vlan-tagging")
         self.deferred.callback(self)
     except Exception as e:
         self.log.exception('setting-vlan-tagging', e=e)
         self.deferred.errback(failure.Failure(e))
Example #20
0
 def _on_timeout(err):
     all_states = [_svc.state for _svc in services().values()]
     if 'INFLUENCE' in all_states or 'STARTING' in all_states or 'STOPPING' in all_states:
         restart_result.errback(failure.Failure(Exception('timeout')))
         return err
     _do_stop()
     return None
    def perform_delete(self):
        """ Perform the delete requests """
        self.log.debug('perform-delete')

        try:
            for me in self._me_tuples:
                class_id = me[0]
                entity_id = me[1]

                frame = OmciFrame(transaction_id=None,
                                  message_type=OmciDelete.message_id,
                                  omci_message=OmciDelete(
                                      entity_class=class_id,
                                      entity_id=entity_id))
                self.strobe_watchdog()
                results = yield self._device.omci_cc.send(frame)

                status = results.fields['omci_message'].fields['success_code']
                self.log.debug('perform-delete-status', status=status)

                # Did it fail, it instance does not exist, not an error
                if status != RC.Success.value and status != RC.UnknownInstance.value:
                    msg = 'ME: {}, entity: {} failed with status {}'.format(
                        class_id, entity_id, status)
                    raise DeletePMException(msg)

                self.log.debug('delete-pm-success',
                               class_id=class_id,
                               entity_id=entity_id)
            self.deferred.callback(self)

        except Exception as e:
            self.log.exception('perform-create', e=e)
            self.deferred.errback(failure.Failure(e))
Example #22
0
    def perform_get_omci(self):
        """
        Perform the initial get request
        """
        self.log.info('perform-get')

        try:
            frame = MEFrame(self._entity_class, self._entity_id,
                            self._attributes).get()
            self.strobe_watchdog()
            results = yield self._device.omci_cc.send(frame)

            status = results.fields['omci_message'].fields['success_code']
            self.log.info('perform-get-status', status=status)

            # Success?
            if status == RC.Success.value:
                self._results = results
                results_omci = results.fields['omci_message'].fields

                # Were all attributes fetched?
                missing_attr = frame.fields['omci_message'].fields['attributes_mask'] ^ \
                    results_omci['attributes_mask']

                if missing_attr > 0:
                    self.strobe_watchdog()
                    self._local_deferred = reactor.callLater(
                        0, self.perform_get_missing_attributes, missing_attr)
                    returnValue(self._local_deferred)

            elif status == RC.AttributeFailure.value:
                # What failed?  Note if only one attribute was attempted, then
                # that is an overall failure

                if not self._allow_failure or len(self._attributes) <= 1:
                    raise GetException(
                        'Get failed with status code: {}'.format(
                            RC.AttributeFailure.value))

                self.strobe_watchdog()
                self._local_deferred = reactor.callLater(
                    0, self.perform_get_failed_attributes, results,
                    self._attributes)
                returnValue(self._local_deferred)

            else:
                raise GetException(
                    'Get failed with status code: {}'.format(status))

            self.log.info('get-completed')
            self.deferred.callback(self)

        except Exception as e:
            self.log.exception('perform-get',
                               e=e,
                               class_id=self._entity_class,
                               entity_id=self._entity_id,
                               attributes=self._attributes)
            self.deferred.errback(failure.Failure(e))
Example #23
0
    def perform_mib_download(self):
        """
        Send the commands to minimally configure the PON, Bridge, and
        UNI ports for this device. The application of any service flows
        and other characteristics are done as needed.
        """
        self.log.debug('function-entry')
        self.log.info('perform-download')

        device = self._handler.adapter_agent.get_device(self.device_id)

        def resources_available():
            return (len(self._handler.uni_ports) > 0 and
                    len(self._handler.pon_port.tconts) and
                    len(self._handler.pon_port.gem_ports))

        if self._handler.enabled and resources_available():
            device.reason = 'performing-initial-mib-download'
            self._handler.adapter_agent.update_device(device)

            try:
                # Lock the UNI ports to prevent any alarms during initial configuration
                # of the ONU
                self.strobe_watchdog()
                yield self.enable_uni(self._uni_port, True)

                # Provision the initial bridge configuration
                yield self.perform_initial_bridge_setup()

                # And not all the service specific work
                yield self.perform_service_specific_steps()

                # And re-enable the UNIs if needed
                yield self.enable_uni(self._uni_port, False)

                self.deferred.callback('initial-download-success')

            except TimeoutError as e:
                self.deferred.errback(failure.Failure(e))

        else:
            e = MibResourcesFailure('Required resources are not available',
                                    tconts=len(self._handler.pon_port.tconts),
                                    gems=len(self._handler.pon_port.gem_ports),
                                    unis=len(self._handler.uni_ports))
            self.deferred.errback(failure.Failure(e))
Example #24
0
 def ebRequestWriting(err):
     if self._state == 'TRANSMITTING':
         self._state = 'GENERATION_FAILED'
         self.transport.loseConnection()
         self._finishedRequest.errback(
             failure.Failure(RequestGenerationFailed([err])))
     else:
         log.err(err, 'Error writing request, but not in valid state '
                      'to finalize request: %s' % self._state)
Example #25
0
    def perform_reboot(self):
        """
        Perform the reboot requests

        Depending on the ONU implementation, a response may not be returned. For this
        reason, a timeout is considered successful.
        """
        self.log.info('perform-reboot')

        try:
            frame = OntGFrame().reboot(reboot_code=self._flags)
            self.strobe_watchdog()
            results = yield self._device.omci_cc.send(frame,
                                                      timeout=self._timeout,
                                                      high_priority=True)

            status = results.fields['omci_message'].fields['success_code']
            self.log.debug('reboot-status', status=status)

            # Did it fail
            if status != RC.Success.value:
                if self._flags != RebootFlags.Reboot_Unconditionally and\
                        status == RC.DeviceBusy.value:
                    raise DeviceBusy('ONU is busy, try again later')
                else:
                    msg = 'Reboot request failed with status {}'.format(status)
                    raise RebootException(msg)

            self.log.info('reboot-success')
            self.deferred.callback(self)

        except TimeoutError:
            self.log.info('timeout',
                          msg='Request timeout is not considered an error')
            self.deferred.callback(None)

        except DeviceBusy as e:
            self.log.warn('perform-reboot', msg=e)
            self.deferred.errback(failure.Failure(e))

        except Exception as e:
            self.log.exception('perform-reboot', e=e)
            self.deferred.errback(failure.Failure(e))
Example #26
0
    def perform_service_download(self):
        """
        Send the commands to minimally configure the PON, Bridge, and
        UNI ports for this device. The application of any service flows
        and other characteristics are done once resources (gem-ports, tconts, ...)
        have been defined.
        """
        self.log.debug('perform-service-download')
        device = self._handler.adapter_agent.get_device(self.device_id)

        def resources_available():
            return (len(self._handler.uni_ports) > 0 and len(self._pon.tconts)
                    and len(self._pon.gem_ports))

        if self._handler.enabled and resources_available():
            device.reason = 'Performing Service OMCI Download'
            self._handler.adapter_agent.update_device(device)

            try:
                # Lock the UNI ports to prevent any alarms during initial configuration
                # of the ONU
                self.strobe_watchdog()
                # Provision the initial bridge configuration
                yield self.perform_service_specific_steps()

                # And re-enable the UNIs if needed
                yield self.enable_unis(self._handler.uni_ports, False)

                # If here, we are done
                device = self._handler.adapter_agent.get_device(self.device_id)
                device.reason = ''
                self._handler.adapter_agent.update_device(device)
                self.deferred.callback('service-download-success')

            except TimeoutError as e:
                self.deferred.errback(failure.Failure(e))

            except Exception as e:
                self.deferred.errback(failure.Failure(e))
        else:
            # TODO: Provide better error reason, what was missing...
            e = ServiceResourcesFailure('Required resources are not available')
            self.deferred.errback(failure.Failure(e))
Example #27
0
    def perform_lock(self):
        """
        Perform the lock/unlock
        """
        self.log.info('setting-uni-lock-state', lock=self._lock)

        try:
            state = 1 if self._lock else 0

            # lock the whole ont and all the pptp.  some onu dont causing odd behavior.
            msg = OntGFrame(attributes={'administrative_state': state})
            frame = msg.set()
            self.log.debug('openomci-msg', msg=msg)
            results = yield self._device.omci_cc.send(frame)
            self.strobe_watchdog()

            status = results.fields['omci_message'].fields['success_code']
            self.log.info('response-status', status=status)

            # Success?
            if status in (RC.Success.value, RC.InstanceExists):
                self.log.debug('set-lock-ontg', lock=self._lock)
            else:
                self.log.warn('cannot-set-lock-ontg', lock=self._lock)

            pptp = self._config.pptp_entities

            for key, value in pptp.iteritems():
                msg = PptpEthernetUniFrame(
                    key, attributes=dict(administrative_state=state))
                frame = msg.set()
                self.log.debug('openomci-msg', msg=msg)
                results = yield self._device.omci_cc.send(frame)
                self.strobe_watchdog()

                status = results.fields['omci_message'].fields['success_code']
                self.log.info('response-status', status=status)

                # Success?
                if status in (RC.Success.value, RC.InstanceExists):
                    self.log.debug('set-lock-uni',
                                   uni=key,
                                   value=value,
                                   lock=self._lock)
                else:
                    self.log.warn('cannot-set-lock-uni',
                                  uni=key,
                                  value=value,
                                  lock=self._lock)

            self.deferred.callback(self)

        except Exception as e:
            self.log.exception('setting-uni-lock-state', e=e)
            self.deferred.errback(failure.Failure(e))
Example #28
0
    def get_supported_entities(self):
        """
        Get the supported ME Types for this ONU.
        """
        try:
            # Get the number of requests needed
            frame = OmciFrame(me_type_table=True).get()
            self.strobe_watchdog()
            results = yield self._device.omci_cc.send(frame)

            omci_msg = results.fields['omci_message']
            status = omci_msg.fields['success_code']

            if status != ReasonCodes.Success.value:
                raise GetCapabilitiesFailure(
                    'Get count of supported entities failed with status code: {}'
                    .format(status))
            data = omci_msg.fields['data']['me_type_table']
            count = self.get_count_from_data_buffer(bytearray(data))

            seq_no = 0
            data_buffer = bytearray(0)
            self.log.debug('me-type-count', octets=count, data=hexlify(data))

            # Start the loop
            for offset in xrange(0, count, self._pdu_size):
                frame = OmciFrame(me_type_table=seq_no).get_next()
                seq_no += 1
                self.strobe_watchdog()
                results = yield self._device.omci_cc.send(frame)

                omci_msg = results.fields['omci_message']
                status = omci_msg.fields['success_code']

                if status != ReasonCodes.Success.value:
                    raise GetCapabilitiesFailure(
                        'Get supported entities request at offset {} of {} failed with status code: {}'
                        .format(offset + 1, count, status))

                # Extract the data
                num_octets = count - offset
                if num_octets > self._pdu_size:
                    num_octets = self._pdu_size

                data = omci_msg.fields['data']['me_type_table']
                data_buffer += bytearray(data[:num_octets])

            me_types = {(data_buffer[x] << 8) + data_buffer[x + 1]
                        for x in xrange(0, len(data_buffer), 2)}
            returnValue(me_types)

        except Exception as e:
            self.log.exception('get-entities', e=e)
            self.deferred.errback(failure.Failure(e))
    def delete_gem_port_nw_ctp_and_associated_me(self):
        self.log.info('deleting-gem-port-iw')

        omci_cc = self._onu_device.omci_cc
        try:
            ################################################################################
            # Delete GemPortNetworkCTP and GemPortInterworkingPoint
            ################################################################################
            # The _gem_port.remove_from_hardware is already doing check_status_and_state
            yield self._gem_port.remove_from_hardware(omci_cc)

            self.deferred.callback("tech-profile-remove-success--gem-port")

        except TimeoutError as e:
            self.log.warn('rx-timeout-tech-profile', e=e)
            self.deferred.errback(failure.Failure(e))

        except Exception as e:
            self.log.exception('omci-delete-tech-profile', e=e)
            self.deferred.errback(failure.Failure(e))
Example #30
0
    def perform_mib_download(self):
        """
        Send the commands to minimally configure the PON, Bridge, and
        UNI ports for this device. The application of any service flows
        and other characteristics are done once resources (gem-ports, tconts, ...)
        have been defined.
        """
        self.log.info('perform-initial-download')

        device = self._handler.adapter_agent.get_device(self.device_id)

        def resources_available():
            return len(self._handler.uni_ports) > 0

        if self._handler.enabled and resources_available():
            device.reason = 'Performing Initial OMCI Download'
            self._handler.adapter_agent.update_device(device)

            try:
                # Lock the UNI ports to prevent any alarms during initial configuration
                # of the ONU
                self.strobe_watchdog()
                # yield self.enable_unis(self._handler.uni_ports, True)

                # Provision the initial bridge configuration
                yield self.perform_initial_bridge_setup()

                # If here, we are done with the generic MIB download
                device = self._handler.adapter_agent.get_device(self.device_id)

                device.reason = 'Initial OMCI Download Complete'
                self._handler.adapter_agent.update_device(device)
                self.deferred.callback('MIB Download - success')

            except TimeoutError as e:
                self.deferred.errback(failure.Failure(e))

        else:
            # TODO: Provide better error reason, what was missing...
            e = MibResourcesFailure('ONU is not enabled')
            self.deferred.errback(failure.Failure(e))