blob: c3716cfb133cca8139bd0fe399dc2a4870a1b015 [file] [log] [blame]
#
# Copyright 2017 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
OMCI Managed Entity Frame support
"""
from voltha.extensions.omci.omci import *
from me_frame import MEFrame
class CardholderFrame(MEFrame):
"""
This managed entity represents fixed equipment slot configuration
for the ONU
"""
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))
class CircuitPackFrame(MEFrame):
"""
This managed entity models a real or virtual circuit pack that is equipped in
a real or virtual ONU slot.
"""
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))
class ExtendedVlanTaggingOperationConfigurationDataFrame(MEFrame):
"""
This managed entity organizes data associated with VLAN tagging. Regardless
of its point of attachment, the specified tagging operations refer to the
upstream direction.
"""
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(ExtendedVlanTaggingOperationConfigurationDataFrame,
self).__init__(ExtendedVlanTaggingOperationConfigurationData,
entity_id,
MEFrame._attr_to_data(attributes))
class IpHostConfigDataFrame(MEFrame):
"""
The IP host config data configures IPv4 based services offered on the ONU.
"""
def __init__(self, entity_id, attributes):
"""
: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(IpHostConfigDataFrame, self).__init__(IpHostConfigData,
entity_id,
MEFrame._attr_to_data(attributes))
class GalEthernetProfileFrame(MEFrame):
"""
This managed entity organizes data that describe the GTC adaptation layer
processing functions of the ONU for Ethernet services.
"""
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)
class GemInterworkingTpFrame(MEFrame):
"""
An instance of this managed entity represents a point in the ONU where the
interworking of a bearer service (usually Ethernet) to the GEM layer takes
place.
"""
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)
class GemPortNetworkCtpFrame(MEFrame):
"""
This managed entity represents the termination of a GEM port on an ONU.
"""
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)
class Ieee8021pMapperServiceProfileFrame(MEFrame):
"""
This managed entity associates the priorities of IEEE 802.1p [IEEE
802.1D] priority tagged frames with specific connections.
"""
def __init__(self, entity_id, tp_pointer=None, interwork_tp_pointers=None):
"""
:param entity_id: (int) This attribute uniquely identifies each instance of
this managed entity. (0..65535)
:param tp_pointer: (int) This attribute points to an instance of the
associated termination point. (0..65535)
:param interwork_tp_pointers: (list) List of 1 to 8 interworking termination
point IDs. The first entry is assigned
got p-bit priority 0. If less than 8 IDs
are provided, the last ID is used for
the remaining items.
"""
if tp_pointer is None and interwork_tp_pointers is None:
data = dict(
tp_pointer=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_0=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_1=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_2=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_3=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_4=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_5=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_6=OmciNullPointer,
interwork_tp_pointer_for_p_bit_priority_7=OmciNullPointer
)
else:
self.check_type(tp_pointer, (list, type(None)))
self.check_type(interwork_tp_pointers, (list, type(None)))
data = dict()
if tp_pointer is not None:
data['tp_pointer'] = tp_pointer
if interwork_tp_pointers is not None:
assert all(isinstance(tp, int) and 0 <= tp <= 0xFFFF
for tp in interwork_tp_pointers),\
'Interworking TP IDs must be 0..0xFFFF'
assert 1 <= len(interwork_tp_pointers) <= 8, \
'Invalid number of Interworking TP IDs. Must be 1..8'
data = dict()
for pbit in range(0, len(interwork_tp_pointers)):
data['interwork_tp_pointer_for_p_bit_priority_{}'.format(pbit)] = \
interwork_tp_pointers[pbit]
for pbit in range(len(interwork_tp_pointers), 7):
data['interwork_tp_pointer_for_p_bit_priority_{}'.format(pbit)] = \
interwork_tp_pointers[len(interwork_tp_pointers) - 1]
super(Ieee8021pMapperServiceProfileFrame, self).__init__(Ieee8021pMapperServiceProfile,
entity_id,
data)
class MacBridgePortConfigurationDataFrame(MEFrame):
"""
This managed entity represents the ONU as equipment.
"""
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)
class MacBridgeServiceProfileFrame(MEFrame):
"""
This managed entity models a MAC bridge in its entirety; any number
of ports may be associated with the bridge through pointers to the
MAC bridge service profile managed entity.
"""
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(MacBridgeServiceProfileFrame, self).__init__(MacBridgeServiceProfile,
entity_id,
MEFrame._attr_to_data(attributes))
class OntGFrame(MEFrame):
"""
This managed entity represents the ONU as equipment.
"""
def __init__(self, attributes):
"""
: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))
class Ont2GFrame(MEFrame):
"""
This managed entity contains additional attributes associated with a PON ONU.
"""
def __init__(self, attributes):
"""
: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.
"""
# Only one managed entity instance (Entity ID=0)
super(Ont2GFrame, self).__init__(Ont2G, 0,
MEFrame._attr_to_data(attributes))
class PptpEthernetUniFrame(MEFrame):
"""
This managed entity represents the point at an Ethernet UNI where the physical path
terminates and Ethernet physical level functions are performed.
"""
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(PptpEthernetUniFrame, self).__init__(PptpEthernetUni, entity_id,
MEFrame._attr_to_data(attributes))
class SoftwareImageFrame(MEFrame):
"""
This managed entity models an executable software image stored in the ONU.
"""
def __init__(self, entity_id):
"""
:param entity_id: (int) This attribute uniquely identifies each instance of
this managed entity. (0..65535)
"""
super(SoftwareImageFrame, self).__init__(SoftwareImage, entity_id, None)
class TcontFrame(MEFrame):
"""
An instance of the traffic container managed entity T-CONT represents a
logical connection group associated with a G-PON PLOAM layer alloc-ID.
"""
def __init__(self, entity_id, alloc_id=None, policy=None):
"""
:param entity_id: (int) This attribute uniquely identifies each instance of
this managed entity. (0..65535)
:param alloc_id: (int) This attribute links the T-CONT with the alloc-ID
assigned by the OLT in the assign_alloc-ID PLOAM
message (0..0xFFF)
:param policy: (int) This attribute indicates the T-CONT's traffic scheduling
policy. Valid values:
0 - Null
1 - Strict priority
2 - WRR - Weighted round robin
"""
# Validate
self.check_type(alloc_id, (int, type(None)))
self.check_type(policy, (int, type(None)))
if alloc_id is not None and not 0 <= alloc_id <= 0xFFF:
raise ValueError('alloc_id should be 0..0xFFF')
if policy is not None and not 0 <= policy <= 2:
raise ValueError('policy should be 0..2')
if alloc_id is None and policy is None:
data = None
else:
data = dict()
if alloc_id is not None:
data['alloc_id'] = alloc_id
if policy is not None:
data['policy'] = policy
super(TcontFrame, self).__init__(Tcont, entity_id, data)
class VlanTaggingFilterDataFrame(MEFrame):
"""
An instance of this managed entity represents a point in the ONU where the
interworking of a bearer service (usually Ethernet) to the GEM layer takes
place.
"""
def __init__(self, entity_id, vlan_tcis=None, forward_operation=None):
"""
:param entity_id: (int) This attribute uniquely identifies each instance of
this managed entity. (0..65535)
:param vlan_tcis: (list) This attribute is a list of provisioned TCI values
for the bridge port. (0..0xFFFF)
:param forward_operation: (int) What to do. See ITU spec for more information
"""
# Validate
self.check_type(vlan_tcis, (list, type(None)))
self.check_type(forward_operation, (int, type(None)))
if forward_operation is not None and not 0 <= forward_operation <= 0x21:
raise ValueError('forward_operation should be 0..0x21')
if vlan_tcis is None and forward_operation is None:
data = None
else:
data = dict()
if vlan_tcis is not None:
assert all(isinstance(tci, int) and 0 <= tci <= 0xFFFF
for tci in vlan_tcis), "VLAN TCI's are 0..0xFFFF"
assert 1 <= len(vlan_tcis) <= 12, 'Number of VLAN TCI values is 1..12'
for index in range(0, len(vlan_tcis)):
data['vlan_filter_{}'.format(index)] = vlan_tcis[index]
data['number_of_entries'] = len(vlan_tcis)
if forward_operation is not None:
assert 0 <= forward_operation <= 0x21, 'forwarding_operation must be 0x00..0x21'
data['forward_operation'] = forward_operation
super(VlanTaggingFilterDataFrame, self).__init__(VlanTaggingFilterData,
entity_id,
data)