def __init__(self, attributes=None): """ :param attributes: (basestring, list, set, dict) attributes. For gets a string, list, or set can be provided. For create/set operations, a dictionary should be provided, for deletes None may be specified. """ super(OntGFrame, self).__init__(OntG, 0, MEFrame._attr_to_data(attributes))
def __init__(self, entity_id, max_gem_payload_size=None): """ :param entity_id: (int) This attribute uniquely identifies each instance of this managed entity. (0..65535) :param max_gem_payload_size: (int) This attribute defines the maximum payload size generated in the associated GEM interworking termination point managed entity. (0..65535 """ MEFrame.check_type(max_gem_payload_size, (int, type(None))) if max_gem_payload_size is not None and not 0 <= max_gem_payload_size <= 0xFFFF: # TODO: verify min/max raise ValueError('max_gem_payload_size should be 0..0xFFFF') data = None if max_gem_payload_size is None else\ { 'max_gem_payload_size': max_gem_payload_size } super(GalEthernetProfileFrame, self).__init__(GalEthernetProfile, entity_id, data)
def __init__(self, entity_id, attributes=None): """ :param entity_id: (int) This attribute uniquely identifies each instance of this managed entity. (0..65535) :param attributes: (basestring, list, set, dict) attributes. For gets a string, list, or set can be provided. For create/set operations, a dictionary should be provided, for deletes None may be specified. """ super(VeipUniFrame, self).__init__(VeipUni, entity_id, MEFrame._attr_to_data(attributes))
def __init__(self, single, slot_number, attributes): """ :param single:(bool) True if the ONU is a single piece of integrated equipment, False if the ONU contains pluggable equipment modules :param slot_number: (int) slot number (0..254) :param attributes: (basestring, list, set, dict) attributes. For gets a string, list, or set can be provided. For create/set operations, a dictionary should be provided, for deletes None may be specified. """ # Validate MEFrame.check_type(single, bool) MEFrame.check_type(slot_number, int) if not 0 <= slot_number <= 254: raise ValueError('slot_number should be 0..254') entity_id = 256 + slot_number if single else slot_number super(CardholderFrame, self).__init__(Cardholder, entity_id, MEFrame._attr_to_data(attributes))
def __init__(self, entity_id, attributes): """ :param entity_id: (int) This attribute uniquely identifies each instance of this managed entity. Its value is the same as that of the cardholder managed entity containing this circuit pack instance. (0..65535) :param attributes: (basestring, list, set, dict) attributes. For gets a string, list, or set can be provided. For create/set operations, a dictionary should be provided, for deletes None may be specified. """ super(CircuitPackFrame, self).__init__(CircuitPack, entity_id, MEFrame._attr_to_data(attributes))
def __init__(self, entity_id, attributes): """ :param entity_id: (int) TThis attribute uniquely identifies each instance of this managed entity. Through an identical ID, this managed entity is implicitly linked to an instance of the ANI-G. :param attributes: (basestring, list, set, dict) attributes. For gets a string, list, or set can be provided. For set operations, a dictionary should be provided, for deletes None may be specified. """ super(XgPonUpstreamPerformanceMonitoringHistoryDataFrame, self).__init__(XgPonUpstreamPerformanceMonitoringHistoryData, entity_id, MEFrame._attr_to_data(attributes))
def __init__(self, entity_id, bridge_id_pointer=None, port_num=None, tp_type=None, tp_pointer=None, attributes=None): """ :param entity_id: (int) This attribute uniquely identifies each instance of this managed entity. (0..65535) :param bridge_id_pointer: (int) This attribute points to an instance of the MAC bridge service profile. (0..65535) :param port_num: (int) This attribute is the bridge port number. (0..255) :param tp_type: (int) This attribute identifies the type of termination point associated with this MAC bridge port. Valid values are: 1 Physical path termination point Ethernet UNI 2 Interworking VCC termination point 3 IEEE 802.1p mapper service profile 4 IP host config data or IPv6 host config data 5 GEM interworking termination point 6 Multicast GEM interworking termination point 7 Physical path termination point xDSL UNI part 1 8 Physical path termination point VDSL UNI 9 Ethernet flow termination point 10 Reserved 11 Virtual Ethernet interface point 12 Physical path termination point MoCA UNI :param tp_pointer: (int) This attribute points to the termination point associated with this MAC bridge por. (0..65535) :param attributes: (basestring, list, set, dict) additional ME attributes. not specifically specified as a parameter. For gets a string, list, or set can be provided. For create/set operations, a dictionary should be provided, for deletes None may be specified. """ # Validate self.check_type(bridge_id_pointer, (int, type(None))) self.check_type(port_num, (int, type(None))) self.check_type(tp_type, (int, type(None))) self.check_type(tp_pointer, (int, type(None))) if bridge_id_pointer is not None and not 0 <= bridge_id_pointer <= 0xFFFE: # TODO: Verify max raise ValueError('bridge_id_pointer should be 0..0xFFFE') if port_num is not None and not 0 <= port_num <= 255: raise ValueError( 'port_num should be 0..255') # TODO: Verify min,max if tp_type is not None and not 1 <= tp_type <= 12: raise ValueError('service_profile_pointer should be 1..12') if tp_pointer is not None and not 0 <= tp_pointer <= 0xFFFE: # TODO: Verify max raise ValueError('interworking_tp_pointer should be 0..0xFFFE') data = MEFrame._attr_to_data(attributes) if bridge_id_pointer is not None or \ port_num is not None or \ tp_type is not None or \ tp_pointer is not None: data = data or dict() if bridge_id_pointer is not None: data['bridge_id_pointer'] = bridge_id_pointer if port_num is not None: data['port_num'] = port_num if tp_type is not None: data['tp_type'] = tp_type if tp_pointer is not None: data['tp_pointer'] = tp_pointer super(MacBridgePortConfigurationDataFrame, self).\ __init__(MacBridgePortConfigurationData, entity_id, data)
def __init__(self, entity_id, port_id=None, tcont_id=None, direction=None, upstream_tm=None, attributes=None): """ :param entity_id: (int) This attribute uniquely identifies each instance of this managed entity. (0..65535) :param port_id: (int) This attribute is the port-ID of the GEM port associated with this CTP :param tcont_id: (int) This attribute points to a T-CONT instance :param direction: (string) Data direction. Valid values are: 'upstream' - UNI-to-ANI 'downstream' - ANI-to-UNI 'bi-directional' - guess :-) :param upstream_tm: (int) If the traffic management option attribute in the ONU-G ME is 0 (priority controlled) or 2 (priority and rate controlled), this pointer specifies the priority queue ME serving this GEM port network CTP. If the traffic management option attribute is 1 (rate controlled), this attribute redundantly points to the T-CONT serving this GEM port network CTP. :param attributes: (basestring, list, set, dict) additional ME attributes. not specifically specified as a parameter. For gets a string, list, or set can be provided. For create/set operations, a dictionary should be provided, for deletes None may be specified. """ _directions = {"upstream": 1, "downstream": 2, "bi-directional": 3} # Validate self.check_type(port_id, (int, type(None))) self.check_type(tcont_id, (int, type(None))) self.check_type(direction, (basestring, type(None))) self.check_type(upstream_tm, (int, type(None))) if port_id is not None and not 0 <= port_id <= 0xFFFE: # TODO: Verify max raise ValueError('port_id should be 0..0xFFFE') if tcont_id is not None and not 0 <= tcont_id <= 0xFFFE: # TODO: Verify max raise ValueError('tcont_id should be 0..0xFFFE') if direction is not None and str(direction).lower() not in _directions: raise ValueError('direction should one of {}'.format( _directions.keys())) if upstream_tm is not None and not 0 <= upstream_tm <= 0xFFFE: # TODO: Verify max raise ValueError('upstream_tm should be 0..0xFFFE') data = MEFrame._attr_to_data(attributes) if port_id is not None or tcont_id is not None or\ direction is not None or upstream_tm is not None: data = data or dict() if port_id is not None: data['port_id'] = port_id if tcont_id is not None: data['tcont_pointer'] = tcont_id if direction is not None: data['direction'] = _directions[str(direction).lower()] if upstream_tm is not None: data['traffic_management_pointer_upstream'] = upstream_tm super(GemPortNetworkCtpFrame, self).__init__(GemPortNetworkCtp, entity_id, data)
def __init__(self, entity_id, gem_port_network_ctp_pointer=None, interworking_option=None, service_profile_pointer=None, interworking_tp_pointer=None, pptp_counter=None, gal_profile_pointer=None, attributes=None): """ :param entity_id: (int) This attribute uniquely identifies each instance of this managed entity. (0..65535) :param gem_port_network_ctp_pointer: (int) This attribute points to an instance of the GEM port network CTP. (0..65535) :param interworking_option: (int) This attribute identifies the type of non-GEM function that is being interworked. The options are: 0 Circuit-emulated TDM 1 MAC bridged LAN 2 Reserved 3 Reserved 4 Video return path 5 IEEE 802.1p mapper 6 Downstream broadcast 7 MPLS PW TDM service :param service_profile_pointer: (int) This attribute points to an instance of a service profile. CES service profile if interworking option = 0 MAC bridge service profile if interworking option = 1 Video return path service profile if interworking option = 4 IEEE 802.1p mapper service profile if interworking option = 5 Null pointer if interworking option = 6 CES service profile if interworking option = 7 :param interworking_tp_pointer: (int) This attribute is used for the circuit emulation service and IEEE 802.1p mapper service without a MAC bridge. :param gal_profile_pointer: (int) This attribute points to an instance of a service profile. :param attributes: (basestring, list, set, dict) additional ME attributes. not specifically specified as a parameter. For gets a string, list, or set can be provided. For create/set operations, a dictionary should be provided, for deletes None may be specified.. """ # Validate self.check_type(gem_port_network_ctp_pointer, (int, type(None))) self.check_type(interworking_option, (int, type(None))) self.check_type(service_profile_pointer, (int, type(None))) self.check_type(interworking_tp_pointer, (int, type(None))) self.check_type(pptp_counter, (int, type(None))) self.check_type(gal_profile_pointer, (int, type(None))) if gem_port_network_ctp_pointer is not None and not 0 <= gem_port_network_ctp_pointer <= 0xFFFE: # TODO: Verify max raise ValueError( 'gem_port_network_ctp_pointer should be 0..0xFFFE') if interworking_option is not None and not 0 <= interworking_option <= 7: raise ValueError('interworking_option should be 0..7') if service_profile_pointer is not None and not 0 <= service_profile_pointer <= 0xFFFE: # TODO: Verify max raise ValueError('service_profile_pointer should be 0..0xFFFE') if interworking_tp_pointer is not None and not 0 <= interworking_tp_pointer <= 0xFFFE: # TODO: Verify max raise ValueError('interworking_tp_pointer should be 0..0xFFFE') if pptp_counter is not None and not 0 <= pptp_counter <= 255: # TODO: Verify max raise ValueError('pptp_counter should be 0..255') if gal_profile_pointer is not None and not 0 <= gal_profile_pointer <= 0xFFFE: # TODO: Verify max raise ValueError('gal_profile_pointer should be 0..0xFFFE') data = MEFrame._attr_to_data(attributes) if gem_port_network_ctp_pointer is not None or \ interworking_option is not None or \ service_profile_pointer is not None or \ interworking_tp_pointer is not None or \ gal_profile_pointer is not None: data = data or dict() if gem_port_network_ctp_pointer is not None: data[ 'gem_port_network_ctp_pointer'] = gem_port_network_ctp_pointer if interworking_option is not None: data['interworking_option'] = interworking_option if service_profile_pointer is not None: data['service_profile_pointer'] = service_profile_pointer if interworking_tp_pointer is not None: data['interworking_tp_pointer'] = interworking_tp_pointer if gal_profile_pointer is not None: data['gal_profile_pointer'] = gal_profile_pointer super(GemInterworkingTpFrame, self).__init__(GemInterworkingTp, entity_id, data)
def _process_rx_frame(self, timeout, secs, rx_frame, d, tx_frame): omci_msg = rx_frame.fields['omci_message'] if isinstance(omci_msg, OmciGetResponse ) and 'table_attribute_mask' in omci_msg.fields['data']: try: entity_class = omci_msg.fields['entity_class'] entity_id = omci_msg.fields['entity_id'] table_attributes = omci_msg.fields['data'][ 'table_attribute_mask'] device = self._adapter_agent.get_device(self._device_id) if entity_class in self._me_map: ec = self._me_map[entity_class] for index in xrange(16): attr_mask = 1 << index if attr_mask & table_attributes: eca = ec.attributes[index] self.log.debug('omcc-get-table-attribute', table_name=eca.field.name) seq_no = 0 data_buffer = '' count = omci_msg.fields['data'][eca.field.name + '_size'] # Original timeout must be chopped up into each individual get-next request # in order for total transaction to complete within the timeframe of the # original get() timeout. number_transactions = 1 + ( count + OmciTableField.PDU_SIZE - 1) / OmciTableField.PDU_SIZE timeout /= (1 + number_transactions) # Start the loop vals = [] for offset in xrange(0, count, OmciTableField.PDU_SIZE): frame = MEFrame(ec, entity_id, { eca.field.name: seq_no }).get_next() seq_no += 1 max_retries = 3 results = yield self.send( frame, min(timeout / max_retries, secs * 3), max_retries) omci_getnext_msg = results.fields[ 'omci_message'] status = omci_getnext_msg.fields[ 'success_code'] if status != ReasonCodes.Success.value: raise Exception('get-next-failure table=' + eca.field.name + ' entity_id=' + str(entity_id) + ' sqn=' + str(seq_no) + ' omci-status ' + str(status)) # Extract the data num_octets = count - offset if num_octets > OmciTableField.PDU_SIZE: num_octets = OmciTableField.PDU_SIZE data = omci_getnext_msg.fields['data'][ eca.field.name] data_buffer += data[:num_octets] while data_buffer: data_buffer, val = eca.field.getfield( None, data_buffer) vals.append(val) omci_msg.fields['data'][eca.field.name] = vals del omci_msg.fields['data'][eca.field.name + '_size'] self.log.debug('omcc-got-table-attribute-rows', table_name=eca.field.name, row_count=len(vals)) del omci_msg.fields['data']['table_attribute_mask'] except Exception as e: self.log.exception('get-next-error', e=e) d.errback(failure.Failure(e)) return # Notify sender of completed request reactor.callLater(0, d.callback, rx_frame) # Publish Rx event to listeners in a different task except for internally-consumed get-next-response if not isinstance(omci_msg, OmciGetNextResponse): reactor.callLater(0, self._publish_rx_frame, tx_frame, rx_frame)
def _process_get_rx_frame(self, timeout, secs, rx_frame, d, tx_frame, high_priority): """ Special handling for Get Requests that may require additional 'get_next' operations if a table attribute was requested. """ omci_msg = rx_frame.fields['omci_message'] rx_tid = rx_frame.fields.get('transaction_id') high_priority = self._tid_is_high_priority(rx_tid) frame_index = self._get_priority_index(high_priority) if isinstance(omci_msg, OmciGetResponse) and 'table_attribute_mask' in omci_msg.fields['data']: # save tx request for later so that below send/recv can finish self._tx_request_deferred[frame_index] = self._tx_request[frame_index] self._tx_request[frame_index] = None try: entity_class = omci_msg.fields['entity_class'] entity_id = omci_msg.fields['entity_id'] table_attributes = omci_msg.fields['data']['table_attribute_mask'] # Table attribute mask is encoded opposite of managed entity mask. if entity_class in self._me_map: ec = self._me_map[entity_class] for index in xrange(1, len(ec.attributes) + 1): attr_mask = 1 << index if attr_mask & table_attributes: self.log.debug('omcc-get-table-ec', ec=ec, index=index, attr_mask=attr_mask, table_attributes=table_attributes) eca = ec.attributes[index] self.log.debug('omcc-get-table-attribute', table_name=eca.field.name) seq_no = 0 data_buffer = '' count = omci_msg.fields['data'][eca.field.name + '_size'] if count > MAX_TABLE_ROW_COUNT: self.log.error('omcc-get-table-huge', count=count, name=eca.field.name) raise ValueError('Huge Table Size: {}'.format(count)) # Original timeout must be chopped up into each individual get-next request # in order for total transaction to complete within the timeframe of the # original get() timeout. number_transactions = 1 + (count + OmciTableField.PDU_SIZE - 1) / OmciTableField.PDU_SIZE timeout /= (1 + number_transactions) # Start the loop vals = [] for offset in xrange(0, count, OmciTableField.PDU_SIZE): frame = MEFrame(ec, entity_id, {eca.field.name: seq_no}).get_next() seq_no += 1 max_retries = 3 results = yield self.send(frame, min(timeout / max_retries, secs * 3), max_retries) omci_getnext_msg = results.fields['omci_message'] status = omci_getnext_msg.fields['success_code'] if status != ReasonCodes.Success.value: raise Exception('get-next-failure table=' + eca.field.name + ' entity_id=' + str(entity_id) + ' sqn=' + str(seq_no) + ' omci-status ' + str(status)) # Extract the data num_octets = count - offset if num_octets > OmciTableField.PDU_SIZE: num_octets = OmciTableField.PDU_SIZE data = omci_getnext_msg.fields['data'][eca.field.name] data_buffer += data[:num_octets] while data_buffer: data_buffer, val = eca.field.getfield(None, data_buffer) vals.append(val) omci_msg.fields['data'][eca.field.name] = vals del omci_msg.fields['data'][eca.field.name + '_size'] self.log.debug('omcc-got-table-attribute-rows', table_name=eca.field.name, row_count=len(vals)) del omci_msg.fields['data']['table_attribute_mask'] except Exception as e: self.log.exception('get-next-error', e=e) self._tx_request_deferred[frame_index] = None d.errback(failure.Failure(e), high_priority) return except IndexError as e: self.log.exception('get-next-index-error', e=e) self._tx_request_deferred[frame_index] = None d.errback(failure.Failure(e), high_priority) return # Put it back so the outer Rx/Tx can finish self._tx_request[frame_index] = self._tx_request_deferred[frame_index] self._tx_request_deferred[frame_index] = None # Publish Rx event to listeners in a different task if not isinstance(omci_msg, OmciGetNextResponse): reactor.callLater(0, self._publish_rx_frame, tx_frame, rx_frame) from copy import copy original_callbacks = copy(d.callbacks) self._rx_response[frame_index] = rx_frame d.callback(rx_frame) self.log.debug("finished-processing-get-rx-frame")