Initial commit moving openolt adapter from voltha-go to the new repo.
This version works with ponsim rather than openolt, this is temporary.
It is currently being fixed to work with openolt.

Change-Id: I34a800c98f050140b367e2d474b7aa8b79f34b9a
Signed-off-by: William Kurkian <wkurkian@cisco.com>
diff --git a/python/adapters/extensions/omci/omci_entities.py b/python/adapters/extensions/omci/omci_entities.py
new file mode 100644
index 0000000..95e6581
--- /dev/null
+++ b/python/adapters/extensions/omci/omci_entities.py
@@ -0,0 +1,1564 @@
+#
+# 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.
+#
+import inspect
+
+import sys
+from binascii import hexlify
+from bitstring import BitArray
+import json
+from scapy.fields import ByteField, ShortField, MACField, BitField, IPField
+from scapy.fields import IntField, StrFixedLenField, LongField, FieldListField, PacketLenField
+from scapy.packet import Packet
+
+from voltha.extensions.omci.omci_defs import OmciUninitializedFieldError, \
+    AttributeAccess, OmciNullPointer, EntityOperations, OmciInvalidTypeError
+from voltha.extensions.omci.omci_fields import OmciSerialNumberField, OmciTableField
+from voltha.extensions.omci.omci_defs import bitpos_from_mask
+
+
+class EntityClassAttribute(object):
+
+    def __init__(self, fld, access=set(), optional=False, range_check=None,
+                 avc=False, tca=False, counter=False, deprecated=False):
+        """
+        Initialize an Attribute for a Managed Entity Class
+
+        :param fld: (Field) Scapy field type
+        :param access: (AttributeAccess) Allowed access
+        :param optional: (boolean) If true, attribute is option, else mandatory
+        :param range_check: (callable) None, Lambda, or Function to validate value
+        :param avc: (boolean) If true, an AVC notification can occur for the attribute
+        :param tca: (boolean) If true, a threshold crossing alert alarm notification can occur
+                              for the attribute
+        :param counter: (boolean) If true, this attribute is a PM counter
+        :param deprecated: (boolean) If true, this attribute is deprecated and
+                           only 'read' operations (if-any) performed.
+        """
+        self._fld = fld
+        self._access = access
+        self._optional = optional
+        self._range_check = range_check
+        self._avc = avc
+        self._tca = tca
+        self._counter = counter
+        self._deprecated = deprecated
+
+    @property
+    def field(self):
+        return self._fld
+
+    @property
+    def access(self):
+        return self._access
+
+    @property
+    def optional(self):
+        return self._optional
+
+    @property
+    def is_counter(self):
+        return self._counter
+
+    @property
+    def range_check(self):
+        return self._range_check
+
+    @property
+    def avc_allowed(self):
+        return self._avc
+
+    @property
+    def deprecated(self):
+        return self._deprecated
+
+    _type_checker_map = {
+        'ByteField': lambda val: isinstance(val, (int, long)) and 0 <= val <= 0xFF,
+        'ShortField': lambda val: isinstance(val, (int, long)) and 0 <= val <= 0xFFFF,
+        'IntField': lambda val: isinstance(val, (int, long)) and 0 <= val <= 0xFFFFFFFF,
+        'LongField': lambda val: isinstance(val, (int, long)) and 0 <= val <= 0xFFFFFFFFFFFFFFFF,
+        'StrFixedLenField': lambda val: isinstance(val, basestring),
+        'MACField': lambda val: True,   # TODO: Add a constraint for this field type
+        'BitField': lambda val: True,   # TODO: Add a constraint for this field type
+        'IPField': lambda val: True,    # TODO: Add a constraint for this field type
+        'OmciTableField': lambda val: True,
+
+        # TODO: As additional Scapy field types are used, add constraints
+    }
+
+    def valid(self, value):
+        def _isa_lambda_function(v):
+            import inspect
+            return callable(v) and len(inspect.getargspec(v).args) == 1
+
+        field_type = self.field.__class__.__name__
+        type_check = EntityClassAttribute._type_checker_map.get(field_type,
+                                                                lambda val: True)
+
+        # TODO: Currently StrFixedLenField is used heavily for both bit fields as
+        #       and other 'byte/octet' related strings that are NOT textual. Until
+        #       all of these are corrected, 'StrFixedLenField' cannot test the type
+        #       of the value provided
+
+        if field_type != 'StrFixedLenField' and not type_check(value):
+            return False
+
+        if _isa_lambda_function(self.range_check):
+            return self.range_check(value)
+        return True
+
+
+class EntityClassMeta(type):
+    """
+    Metaclass for EntityClass to generate secondary class attributes
+    for class attributes of the derived classes.
+    """
+    def __init__(cls, name, bases, dct):
+        super(EntityClassMeta, cls).__init__(name, bases, dct)
+
+        # initialize attribute_name_to_index_map
+        cls.attribute_name_to_index_map = dict(
+            (a._fld.name, idx) for idx, a in enumerate(cls.attributes))
+
+
+class EntityClass(object):
+
+    class_id = 'to be filled by subclass'
+    attributes = []
+    mandatory_operations = set()
+    optional_operations = set()
+    notifications = set()
+    alarms = dict()       # Alarm Number -> Alarm Name
+    hidden = False        # If true, this attribute is not reported by a MIB upload.
+                          # This attribute is needed to be able to properly perform
+                          # MIB Audits.
+
+    # will be map of attr_name -> index in attributes, initialized by metaclass
+    attribute_name_to_index_map = None
+    __metaclass__ = EntityClassMeta
+
+    def __init__(self, **kw):
+        assert(isinstance(kw, dict))
+        for k, v in kw.iteritems():
+            assert(k in self.attribute_name_to_index_map)
+        self._data = kw
+
+    def serialize(self, mask=None, operation=None):
+        octets = ''
+
+        # generate ordered list of attribute indices needed to be processed
+        # if mask is provided, we use that explicitly
+        # if mask is not provided, we determine attributes from the self._data
+        # content also taking into account the type of operation in hand
+        if mask is not None:
+            attribute_indices = EntityClass.attribute_indices_from_mask(mask)
+        else:
+            attribute_indices = self.attribute_indices_from_data()
+
+        # Serialize each indexed field (ignoring entity id)
+        for index in attribute_indices:
+            eca = self.attributes[index]
+            field = eca.field
+            try:
+                value = self._data[field.name]
+
+                if not eca.valid(value):
+                    raise OmciInvalidTypeError(
+                        'Value "{}" for Entity field "{}" is not valid'.format(value,
+                                                                               field.name))
+            except KeyError:
+                raise OmciUninitializedFieldError(
+                    'Entity field "{}" not set'.format(field.name))
+
+            octets = field.addfield(None, octets, value)
+
+        return octets
+
+    def attribute_indices_from_data(self):
+        return sorted(
+            self.attribute_name_to_index_map[attr_name]
+            for attr_name in self._data.iterkeys())
+
+    byte1_mask_to_attr_indices = dict(
+        (m, bitpos_from_mask(m, 8, -1)) for m in range(256))
+    byte2_mask_to_attr_indices = dict(
+        (m, bitpos_from_mask(m, 16, -1)) for m in range(256))
+
+    @classmethod
+    def attribute_indices_from_mask(cls, mask):
+        # each bit in the 2-byte field denote an attribute index; we use a
+        # lookup table to make lookup a bit faster
+        return \
+            cls.byte1_mask_to_attr_indices[(mask >> 8) & 0xff] + \
+            cls.byte2_mask_to_attr_indices[(mask & 0xff)]
+
+    @classmethod
+    def mask_for(cls, *attr_names):
+        """
+        Return mask value corresponding to given attributes names
+        :param attr_names: Attribute names
+        :return: integer mask value
+        """
+        mask = 0
+        for attr_name in attr_names:
+            index = cls.attribute_name_to_index_map[attr_name]
+            mask |= (1 << (16 - index))
+        return mask
+
+
+# abbreviations
+ECA = EntityClassAttribute
+AA = AttributeAccess
+OP = EntityOperations
+
+
+class OntData(EntityClass):
+    class_id = 2
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: x == 0),
+        # Only 1 octet used if GET/SET operation
+        ECA(ShortField("mib_data_sync", 0), {AA.R, AA.W})
+    ]
+    mandatory_operations = {OP.Get, OP.Set,
+                            OP.GetAllAlarms, OP.GetAllAlarmsNext,
+                            OP.MibReset, OP.MibUpload, OP.MibUploadNext}
+
+
+class Cardholder(EntityClass):
+    class_id = 5
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: 0 <= x < 255 or 256 <= x < 511,
+            avc=True),
+        ECA(ByteField("actual_plugin_unit_type", None), {AA.R}),
+        ECA(ByteField("expected_plugin_unit_type", None), {AA.R, AA.W}),
+        ECA(ByteField("expected_port_count", None), {AA.R, AA.W},
+            optional=True),
+        ECA(StrFixedLenField("expected_equipment_id", None, 20), {AA.R, AA.W},
+            optional=True, avc=True),
+        ECA(StrFixedLenField("actual_equipment_id", None, 20), {AA.R},
+            optional=True),
+        ECA(ByteField("protection_profile_pointer", None), {AA.R},
+            optional=True),
+        ECA(ByteField("invoke_protection_switch", None), {AA.R, AA.W},
+            optional=True, range_check=lambda x: 0 <= x <= 3),
+        ECA(ByteField("alarm_reporting_control", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1, optional=True, avc=True),
+        ECA(ByteField("arc_interval", 0), {AA.R, AA.W}, optional=True),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        0: 'Plug-in circuit pack missing',
+        1: 'Plug-in type mismatch alarm',
+        2: 'Improper card removal',
+        3: 'Plug-in equipment ID mismatch alarm',
+        4: 'Protection switch',
+    }
+
+
+class CircuitPack(EntityClass):
+    class_id = 6
+    attributes = [
+        ECA(StrFixedLenField("managed_entity_id", None, 22), {AA.R, AA.SBC},
+            range_check=lambda x: 0 <= x < 255 or 256 <= x < 511),
+        ECA(ByteField("type", None), {AA.R, AA.SBC}),
+        ECA(ByteField("number_of_ports", None), {AA.R}, optional=True),
+        ECA(OmciSerialNumberField("serial_number"), {AA.R}),
+        ECA(StrFixedLenField("version", None, 14), {AA.R}),
+        ECA(StrFixedLenField("vendor_id", None, 4), {AA.R}),
+        ECA(ByteField("administrative_state", None), {AA.R, AA.W}),
+        ECA(ByteField("operational_state", None), {AA.R}, optional=True, avc=True),
+        ECA(ByteField("bridged_or_ip_ind", None), {AA.R, AA.W}, optional=True,
+            range_check=lambda x: 0 <= x <= 2),
+        ECA(StrFixedLenField("equipment_id", None, 20), {AA.R}, optional=True),
+        ECA(ByteField("card_configuration", None), {AA.R, AA.W, AA.SBC},
+            optional=True),  # not really mandatory, see spec ITU-T G.988, 9.1.6
+        ECA(ByteField("total_tcont_buffer_number", None), {AA.R},
+            optional=True),  # not really mandatory, see spec ITU-T G.988, 9.1.6
+        ECA(ByteField("total_priority_queue_number", None), {AA.R},
+            optional=True),  # not really mandatory, see spec ITU-T G.988, 9.1.6
+        ECA(ByteField("total_traffic_scheduler_number", None), {AA.R},
+            optional=True),  # not really mandatory, see spec ITU-T G.988, 9.1.6
+        ECA(IntField("power_shed_override", None), {AA.R, AA.W},
+            optional=True)
+    ]
+    mandatory_operations = {OP.Get, OP.Set, OP.Reboot}
+    optional_operations = {OP.Create, OP.Delete, OP.Test}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        0: 'Equipment alarm',
+        1: 'Powering alarm',
+        2: 'Self-test failure',
+        3: 'Laser end of life',
+        4: 'Temperature yellow',
+        5: 'Temperature red',
+    }
+
+class SoftwareImage(EntityClass):
+    class_id = 7
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: 0 <= x/256 <= 254 or 0 <= x % 256 <= 1),
+        ECA(StrFixedLenField("version", None, 14), {AA.R}, avc=True),
+        ECA(ByteField("is_committed", None), {AA.R}, avc=True,
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("is_active", None), {AA.R}, avc=True,
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("is_valid", None), {AA.R}, avc=True,
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(StrFixedLenField("product_code", None, 25), {AA.R}, optional=True, avc=True),
+        ECA(StrFixedLenField("image_hash", None, 16), {AA.R}, optional=True, avc=True),
+    ]
+    mandatory_operations = {OP.Get, OP.StartSoftwareDownload, OP.DownloadSection,
+                            OP.EndSoftwareDownload, OP.ActivateSoftware,
+                            OP.CommitSoftware}
+    notifications = {OP.AttributeValueChange}
+
+
+class PptpEthernetUni(EntityClass):
+    class_id = 11
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(ByteField("expected_type", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 254),
+        ECA(ByteField("sensed_type", 0), {AA.R}, optional=True, avc=True),
+        # TODO: For sensed_type AVC, see note in AT&T OMCI Specification, V3.0, page 123
+        ECA(ByteField("auto_detection_configuration", 0), {AA.R, AA.W},
+            range_check=lambda x: x in [0, 1, 2, 3, 4, 5,
+                                        0x10, 0x11, 0x12, 0x13, 0x14,
+                                        0x20, 0x30], optional=True),  # See ITU-T G.988
+        ECA(ByteField("ethernet_loopback_configuration", 0), {AA.R, AA.W},
+            range_check=lambda x: x in [0, 3]),
+        ECA(ByteField("administrative_state", 1), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("operational_state", 1), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1, optional=True, avc=True),
+        ECA(ByteField("configuration_ind", 0), {AA.R},
+            range_check=lambda x: x in [0, 1, 2, 3, 4, 0x11, 0x12, 0x13]),
+        ECA(ShortField("max_frame_size", 1518), {AA.R, AA.W}, optional=True),
+        ECA(ByteField("dte_or_dce_ind", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 2),
+        ECA(ShortField("pause_time", 0), {AA.R, AA.W}, optional=True),
+        ECA(ByteField("bridged_or_ip_ind", 2), {AA.R, AA.W},
+            optional=True, range_check=lambda x: 0 <= x <= 2),
+        ECA(ByteField("arc", 0), {AA.R, AA.W}, optional=True,
+            range_check=lambda x: 0 <= x <= 1, avc=True),
+        ECA(ByteField("arc_interval", 0), {AA.R, AA.W}, optional=True),
+        ECA(ByteField("pppoe_filter", 0), {AA.R, AA.W}, optional=True),
+        ECA(ByteField("power_control", 0), {AA.R, AA.W}, optional=True),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        0: 'LAN Loss Of Signal',
+    }
+
+
+class MacBridgeServiceProfile(EntityClass):
+    class_id = 45
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("spanning_tree_ind", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("learning_ind", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("port_bridging_ind", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("priority", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("max_age", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0x0600 <= x <= 0x2800),
+        ECA(ShortField("hello_time", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0x0100 <= x <= 0x0A00),
+        ECA(ShortField("forward_delay", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0x0400 <= x <= 0x1E00),
+        ECA(ByteField("unknown_mac_address_discard", None),
+            {AA.R, AA.W, AA.SBC}, range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("mac_learning_depth", None),
+            {AA.R, AA.W, AA.SBC}, optional=True),
+        ECA(ByteField("dynamic_filtering_ageing_time", None),
+            {AA.R, AA.W, AA.SBC}, optional=True),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+
+
+class MacBridgePortConfigurationData(EntityClass):
+    class_id = 47
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ShortField("bridge_id_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("port_num", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("tp_type", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 1 <= x <= 12),
+        ECA(ShortField("tp_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("port_priority", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("port_path_cost", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("port_spanning_tree_in", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("encapsulation_methods", None), {AA.R, AA.W, AA.SBC},
+            optional=True, deprecated=True),
+        ECA(ByteField("lan_fcs_ind", None), {AA.R, AA.W, AA.SBC},
+            optional=True, deprecated=True),
+        ECA(MACField("port_mac_address", None), {AA.R}, optional=True),
+        ECA(ShortField("outbound_td_pointer", None), {AA.R, AA.W},
+            optional=True),
+        ECA(ShortField("inbound_td_pointer", None), {AA.R, AA.W},
+            optional=True),
+        # TODO:
+        ECA(ByteField("mac_learning_depth", 0), {AA.R, AA.W, AA.SBC},
+            optional=True),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Port blocking',
+    }
+
+
+class MacBridgePortFilterPreAssignTable(EntityClass):
+    class_id = 79
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ShortField("ipv4_multicast", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("ipv6_multicast", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("ipv4_broadcast", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("rarp", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("ipx", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("netbeui", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("appletalk", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("bridge_management_information", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("arp", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("pppoe_broadcast", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1)
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+
+
+class VlanTaggingFilterData(EntityClass):
+    class_id = 84
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(FieldListField("vlan_filter_list", None,
+                           ShortField('', 0), count_from=lambda _: 12),
+            {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("forward_operation", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0x00 <= x <= 0x21),
+        ECA(ByteField("number_of_entries", None), {AA.R, AA.W, AA.SBC})
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+
+
+class Ieee8021pMapperServiceProfile(EntityClass):
+    class_id = 130
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ShortField("tp_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_0",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_1",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_2",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_3",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_4",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_5",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_6",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interwork_tp_pointer_for_p_bit_priority_7",
+                       OmciNullPointer), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("unmarked_frame_option", None),
+            {AA.R, AA.W, AA.SBC}, range_check=lambda x: 0 <= x <= 1),
+        ECA(StrFixedLenField("dscp_to_p_bit_mapping", None, length=24),
+            {AA.R, AA.W}),  # TODO: Would a custom 3-bit group bitfield work better?
+        ECA(ByteField("default_p_bit_marking", None),
+            {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("tp_type", None), {AA.R, AA.W, AA.SBC},
+            optional=True, range_check=lambda x: 0 <= x <= 8)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+
+
+class OltG(EntityClass):
+    class_id = 131
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: x == 0),
+        ECA(StrFixedLenField("olt_vendor_id", None, 4), {AA.R, AA.W}),
+        ECA(StrFixedLenField("equipment_id", None, 20), {AA.R, AA.W}),
+        ECA(StrFixedLenField("version", None, 14), {AA.R, AA.W}),
+        ECA(StrFixedLenField("time_of_day_information", None, 14), {AA.R, AA.W})
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+
+
+class OntPowerShedding(EntityClass):
+    class_id = 133
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: x == 0),
+        ECA(ShortField("restore_power_timer_reset_interval", 0),
+            {AA.R, AA.W}),
+        ECA(ShortField("data_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("voice_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("video_overlay_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("video_return_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("dsl_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("atm_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("ces_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("frame_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("sonet_class_shedding_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("shedding_status", None), {AA.R, AA.W}, optional=True,
+            avc=True),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+    notifications = {OP.AttributeValueChange}
+
+
+class IpHostConfigData(EntityClass):
+    class_id = 134
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(BitField("ip_options", 0, size=8), {AA.R, AA.W}),
+        ECA(MACField("mac_address", None), {AA.R}),
+        ECA(StrFixedLenField("onu_identifier", None, 25), {AA.R, AA.W}),
+        ECA(IPField("ip_address", None), {AA.R, AA.W}),
+        ECA(IPField("mask", None), {AA.R, AA.W}),
+        ECA(IPField("gateway", None), {AA.R, AA.W}),
+        ECA(IPField("primary_dns", None), {AA.R, AA.W}),
+        ECA(IPField("secondary_dns", None), {AA.R, AA.W}),
+        ECA(IPField("current_address", None), {AA.R}, avc=True),
+        ECA(IPField("current_mask", None), {AA.R}, avc=True),
+        ECA(IPField("current_gateway", None), {AA.R}, avc=True),
+        ECA(IPField("current_primary_dns", None), {AA.R}, avc=True),
+        ECA(IPField("current_secondary_dns", None), {AA.R}, avc=True),
+        ECA(StrFixedLenField("domain_name", None, 25), {AA.R}, avc=True),
+        ECA(StrFixedLenField("host_name", None, 25), {AA.R}, avc=True),
+        ECA(ShortField("relay_agent_options", None), {AA.R, AA.W},
+            optional=True),
+    ]
+    mandatory_operations = {OP.Get, OP.Set, OP.Test}
+    notifications = {OP.AttributeValueChange}
+
+
+class VlanTaggingOperation(Packet):
+    name = "VlanTaggingOperation"
+    fields_desc = [
+        BitField("filter_outer_priority", 0, 4),
+        BitField("filter_outer_vid", 0, 13),
+        BitField("filter_outer_tpid_de", 0, 3),
+        BitField("pad1", 0, 12),
+
+        BitField("filter_inner_priority", 0, 4),
+        BitField("filter_inner_vid", 0, 13),
+        BitField("filter_inner_tpid_de", 0, 3),
+        BitField("pad2", 0, 8),
+        BitField("filter_ether_type", 0, 4),
+
+        BitField("treatment_tags_to_remove", 0, 2),
+        BitField("pad3", 0, 10),
+        BitField("treatment_outer_priority", 0, 4),
+        BitField("treatment_outer_vid", 0, 13),
+        BitField("treatment_outer_tpid_de", 0, 3),
+
+        BitField("pad4", 0, 12),
+        BitField("treatment_inner_priority", 0, 4),
+        BitField("treatment_inner_vid", 0, 13),
+        BitField("treatment_inner_tpid_de", 0, 3),
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+    @staticmethod
+    def json_from_value(value):
+        bits = BitArray(hex=hexlify(value))
+        temp = VlanTaggingOperation(
+            filter_outer_priority=bits[0:4].uint,         # 4  <-size
+            filter_outer_vid=bits[4:17].uint,             # 13
+            filter_outer_tpid_de=bits[17:20].uint,        # 3
+                                                          # pad 12
+            filter_inner_priority=bits[32:36].uint,       # 4
+            filter_inner_vid=bits[36:49].uint,            # 13
+            filter_inner_tpid_de=bits[49:52].uint,        # 3
+                                                          # pad 8
+            filter_ether_type=bits[60:64].uint,           # 4
+            treatment_tags_to_remove=bits[64:66].uint,    # 2
+                                                          # pad 10
+            treatment_outer_priority=bits[76:80].uint,    # 4
+            treatment_outer_vid=bits[80:93].uint,         # 13
+            treatment_outer_tpid_de=bits[93:96].uint,     # 3
+                                                          # pad 12
+            treatment_inner_priority=bits[108:112].uint,  # 4
+            treatment_inner_vid=bits[112:125].uint,       # 13
+            treatment_inner_tpid_de=bits[125:128].uint,   # 3
+        )
+        return json.dumps(temp.fields, separators=(',', ':'))
+
+    def index(self):
+        return '{:02}'.format(self.fields.get('filter_outer_priority',0)) + \
+               '{:03}'.format(self.fields.get('filter_outer_vid',0)) + \
+               '{:01}'.format(self.fields.get('filter_outer_tpid_de',0)) + \
+               '{:03}'.format(self.fields.get('filter_inner_priority',0)) + \
+               '{:04}'.format(self.fields.get('filter_inner_vid',0)) + \
+               '{:01}'.format(self.fields.get('filter_inner_tpid_de',0)) + \
+               '{:02}'.format(self.fields.get('filter_ether_type',0))
+
+    def is_delete(self):
+        return self.fields.get('treatment_tags_to_remove',0) == 0x3 and \
+            self.fields.get('pad3',0) == 0x3ff and \
+            self.fields.get('treatment_outer_priority',0) == 0xf and \
+            self.fields.get('treatment_outer_vid',0) == 0x1fff and \
+            self.fields.get('treatment_outer_tpid_de',0) == 0x7 and \
+            self.fields.get('pad4',0) == 0xfff and \
+            self.fields.get('treatment_inner_priority',0) == 0xf and \
+            self.fields.get('treatment_inner_vid',0) == 0x1fff and \
+            self.fields.get('treatment_inner_tpid_de',0) == 0x7
+
+    def delete(self):
+        self.fields['treatment_tags_to_remove'] = 0x3
+        self.fields['pad3'] = 0x3ff
+        self.fields['treatment_outer_priority'] = 0xf
+        self.fields['treatment_outer_vid'] = 0x1fff
+        self.fields['treatment_outer_tpid_de'] = 0x7
+        self.fields['pad4'] = 0xfff
+        self.fields['treatment_inner_priority'] = 0xf
+        self.fields['treatment_inner_vid'] = 0x1fff
+        self.fields['treatment_inner_tpid_de'] = 0x7
+        return self
+
+
+class ExtendedVlanTaggingOperationConfigurationData(EntityClass):
+    class_id = 171
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("association_type", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 11),
+        ECA(ShortField("received_vlan_tagging_operation_table_max_size", None),
+            {AA.R}),
+        ECA(ShortField("input_tpid", None), {AA.R, AA.W}),
+        ECA(ShortField("output_tpid", None), {AA.R, AA.W}),
+        ECA(ByteField("downstream_mode", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 8),
+        ECA(OmciTableField(
+            PacketLenField("received_frame_vlan_tagging_operation_table", None,
+                VlanTaggingOperation, length_from=lambda pkt: 16)), {AA.R, AA.W}),
+        ECA(ShortField("associated_me_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(FieldListField("dscp_to_p_bit_mapping", None,
+                           BitField('',  0, size=3), count_from=lambda _: 64),
+            {AA.R, AA.W}),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Set, OP.Get, OP.GetNext}
+    optional_operations = {OP.SetTable}
+
+
+class OntG(EntityClass):
+    class_id = 256
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: x == 0),
+        ECA(StrFixedLenField("vendor_id", None, 4), {AA.R}),
+        ECA(StrFixedLenField("version", None, 14), {AA.R}),
+        ECA(OmciSerialNumberField("serial_number"), {AA.R}),
+        ECA(ByteField("traffic_management_option", None), {AA.R},
+            range_check=lambda x: 0 <= x <= 2),
+        ECA(ByteField("deprecated", 0), {AA.R},
+            optional=True, deprecated=True),
+        ECA(ByteField("battery_backup", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("administrative_state", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("operational_state", None), {AA.R}, optional=True,
+            range_check=lambda x: 0 <= x <= 1, avc=True),
+        ECA(ByteField("ont_survival_time", None), {AA.R}, optional=True),
+        ECA(StrFixedLenField("logical_onu_id", None, 24), {AA.R},
+            optional=True, avc=True),
+        ECA(StrFixedLenField("logical_password", None, 12), {AA.R},
+            optional=True, avc=True),
+        ECA(ByteField("credentials_status", None), {AA.R, AA.W},
+            optional=True, range_check=lambda x: 0 <= x <= 4),
+        ECA(BitField("extended_tc_layer_options", None, size=16), {AA.R},
+            optional=True),
+    ]
+    mandatory_operations = {
+        OP.Get, OP.Set, OP.Reboot, OP.Test, OP.SynchronizeTime}
+    notifications = {OP.TestResult, OP.AttributeValueChange,
+                     OP.AlarmNotification}
+    alarms = {
+        0: 'Equipment alarm',
+        1: 'Powering alarm',
+        2: 'Battery missing',
+        3: 'Battery failure',
+        4: 'Battery low',
+        5: 'Physical intrusion',
+        6: 'Self-test failure',
+        7: 'Dying gasp',
+        8: 'Temperature yellow',
+        9: 'Temperature red',
+        10: 'Voltage yellow',
+        11: 'Voltage red',
+        12: 'ONU manual power off',
+        13: 'Invalid image',
+        14: 'PSE overload yellow',
+        15: 'PSE overload red',
+    }
+
+
+class Ont2G(EntityClass):
+    class_id = 257
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: x == 0),
+        ECA(StrFixedLenField("equipment_id", None, 20), {AA.R}),
+        ECA(ByteField("omcc_version", None), {AA.R}, avc=True),
+        ECA(ShortField("vendor_product_code", None), {AA.R}),
+        ECA(ByteField("security_capability", None), {AA.R},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("security_mode", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("total_priority_queue_number", None), {AA.R}),
+        ECA(ByteField("total_traffic_scheduler_number", None), {AA.R}),
+        ECA(ByteField("deprecated", None), {AA.R}, deprecated=True),
+        ECA(ShortField("total_gem_port_id_number", None), {AA.R}),
+        ECA(IntField("sys_uptime", None), {AA.R}),
+        ECA(BitField("connectivity_capability", None, size=16), {AA.R}),
+        ECA(ByteField("current_connectivity_mode", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 7),
+        ECA(BitField("qos_configuration_flexibility", None, size=16),
+            {AA.R}, optional=True),
+        ECA(ShortField("priority_queue_scale_factor", None), {AA.R, AA.W},
+            optional=True),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+    notifications = {OP.AttributeValueChange}
+
+
+class Tcont(EntityClass):
+    class_id = 262
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(ShortField("alloc_id", None), {AA.R, AA.W}),
+        ECA(ByteField("deprecated", 1), {AA.R}, deprecated=True),
+        ECA(ByteField("policy", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 2),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+
+
+class AniG(EntityClass):
+    class_id = 263
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(ByteField("sr_indication", None), {AA.R}),
+        ECA(ShortField("total_tcont_number", None), {AA.R}),
+        ECA(ShortField("gem_block_length", None), {AA.R, AA.W}),
+        ECA(ByteField("piggyback_dba_reporting", None), {AA.R},
+            range_check=lambda x: 0 <= x <= 4),
+        ECA(ByteField("deprecated", None), {AA.R}, deprecated=True),
+        ECA(ByteField("sf_threshold", 5), {AA.R, AA.W}),
+        ECA(ByteField("sd_threshold", 9), {AA.R, AA.W}),
+        ECA(ByteField("arc", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1, avc=True),
+        ECA(ByteField("arc_interval", 0), {AA.R, AA.W}),
+        ECA(ShortField("optical_signal_level", None), {AA.R}),
+        ECA(ByteField("lower_optical_threshold", 0xFF), {AA.R, AA.W}),
+        ECA(ByteField("upper_optical_threshold", 0xFF), {AA.R, AA.W}),
+        ECA(ShortField("onu_response_time", None), {AA.R}),
+        ECA(ShortField("transmit_optical_level", None), {AA.R}),
+        ECA(ByteField("lower_transmit_power_threshold", 0x81), {AA.R, AA.W}),
+        ECA(ByteField("upper_transmit_power_threshold", 0x81), {AA.R, AA.W}),
+    ]
+    mandatory_operations = {OP.Get, OP.Set, OP.Test}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        0: 'Low received optical power',
+        1: 'High received optical power',
+        2: 'Signal fail',
+        3: 'Signal degrade',
+        4: 'Low transmit optical power',
+        5: 'High transmit optical power',
+        6: 'Laser bias current',
+    }
+
+
+class UniG(EntityClass):
+    class_id = 264
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(ShortField("deprecated", None), {AA.R, AA.W}, deprecated=True),
+        ECA(ByteField("administrative_state", None), {AA.R, AA.W}),
+        ECA(ByteField("management_capability", None), {AA.R},
+            range_check=lambda x: 0 <= x <= 2),
+        ECA(ShortField("non_omci_management_identifier", None), {AA.R, AA.W}),
+        ECA(ShortField("relay_agent_options", None), {AA.R, AA.W},
+            optional=True),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+
+
+class GemInterworkingTp(EntityClass):
+    class_id = 266
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ShortField("gem_port_network_ctp_pointer", None),
+            {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("interworking_option", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 7),
+        ECA(ShortField("service_profile_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interworking_tp_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("pptp_counter", None), {AA.R}, optional=True),
+        ECA(ByteField("operational_state", None), {AA.R}, optional=True,
+            range_check=lambda x: 0 <= x <= 1, avc=True),
+        ECA(ShortField("gal_profile_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("gal_loopback_configuration", 0),
+            {AA.R, AA.W}, range_check=lambda x: 0 <= x <= 1),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        6: 'Operational state change',
+    }
+
+
+class GemPortNetworkCtp(EntityClass):
+    class_id = 268
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ShortField("port_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("tcont_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("direction", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 1 <= x <= 3),
+        ECA(ShortField("traffic_management_pointer_upstream", None),
+            {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("traffic_descriptor_profile_pointer", None),
+            {AA.R, AA.W, AA.SBC}, optional=True),
+        ECA(ByteField("uni_counter", None), {AA.R}, optional=True),
+        ECA(ShortField("priority_queue_pointer_downstream", None),
+            {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("encryption_state", None), {AA.R}, optional=True),
+        ECA(ShortField("traffic_desc_profile_pointer_downstream", None),
+            {AA.R, AA.W, AA.SBC}, optional=True),
+        ECA(ShortField("encryption_key_ring", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 3)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        5: 'End-to-end loss of continuity',
+    }
+
+
+class GalEthernetProfile(EntityClass):
+    class_id = 272
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ShortField("max_gem_payload_size", None), {AA.R, AA.W, AA.SBC}),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+
+
+class PriorityQueueG(EntityClass):
+    class_id = 277
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(ByteField("queue_configuration_option", None), {AA.R},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("maximum_queue_size", None), {AA.R}),
+        ECA(ShortField("allocated_queue_size", None), {AA.R, AA.W}),
+        ECA(ShortField("discard_block_counter_reset_interval", None), {AA.R, AA.W}),
+        ECA(ShortField("threshold_value_for_discarded_blocks", None), {AA.R, AA.W}),
+        ECA(IntField("related_port", None), {AA.R}),
+        ECA(ShortField("traffic_scheduler_pointer", 0), {AA.R, AA.W}),
+        ECA(ByteField("weight", 1), {AA.R, AA.W}),
+        ECA(ShortField("back_pressure_operation", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(IntField("back_pressure_time", 0), {AA.R, AA.W}),
+        ECA(ShortField("back_pressure_occur_queue_threshold", None), {AA.R, AA.W}),
+        ECA(ShortField("back_pressure_clear_queue_threshold", None), {AA.R, AA.W}),
+        # TODO: Custom field of 4 2-byte values would help below
+        ECA(LongField("packet_drop_queue_thresholds", None), {AA.R, AA.W},
+            optional=True),
+        ECA(ShortField("packet_drop_max_p", 0xFFFF), {AA.R, AA.W}, optional=True),
+        ECA(ByteField("queue_drop_w_q", 9), {AA.R, AA.W}, optional=True),
+        ECA(ByteField("drop_precedence_colour_marking", 0), {AA.R, AA.W},
+            optional=True, range_check=lambda x: 0 <= x <= 7),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Block loss',
+    }
+
+
+class TrafficSchedulerG(EntityClass):
+    class_id = 278
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(ShortField("tcont_pointer", None), {AA.R}),
+        ECA(ShortField("traffic_scheduler_pointer", None), {AA.R}),
+        ECA(ByteField("policy", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 2),
+        ECA(ByteField("priority_weight", 0), {AA.R, AA.W}),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+
+
+class MulticastGemInterworkingTp(EntityClass):
+    class_id = 281
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC},
+            range_check=lambda x: x != OmciNullPointer),
+        ECA(ShortField("gem_port_network_ctp_pointer", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interworking_option", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: x in [0, 1, 3, 5]),
+        ECA(ShortField("service_profile_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("interworking_tp_pointer", 0), {AA.R, AA.W, AA.SBC},
+            deprecated=True),
+        ECA(ByteField("pptp_counter", None), {AA.R}),
+        ECA(ByteField("operational_state", None), {AA.R}, avc=True,
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("gal_profile_pointer", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("gal_loopback_configuration", None), {AA.R, AA.W, AA.SBC},
+            deprecated=True),
+        # TODO add multicast_address_table here (page 85 of spec.)
+        # ECA(...("multicast_address_table", None), {AA.R, AA.W})
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.GetNext, OP.Set}
+    optional_operations = {OP.SetTable}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        0: 'Deprecated',
+    }
+
+
+class AccessControlRow0(Packet):
+    name = "AccessControlRow0"
+    fields_desc = [
+        BitField("set_ctrl", 0, 2),
+        BitField("row_part_id", 0, 3),
+        BitField("test", 0, 1),
+        BitField("row_key", 0, 10),
+
+        ShortField("gem_port_id", None),
+        ShortField("vlan_id", None),
+        IPField("src_ip", None),
+        IPField("dst_ip_start", None),
+        IPField("dst_ip_end", None),
+        IntField("ipm_group_bw", None),
+        ShortField("reserved0", 0)
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+
+class AccessControlRow1(Packet):
+    name = "AccessControlRow1"
+    fields_desc = [
+        BitField("set_ctrl", 0, 2),
+        BitField("row_part_id", 0, 3),
+        BitField("test", 0, 1),
+        BitField("row_key", 0, 10),
+
+        StrFixedLenField("ipv6_src_addr_start_bytes", None, 12),
+        ShortField("preview_length", None),
+        ShortField("preview_repeat_time", None),
+        ShortField("preview_repeat_count", None),
+        ShortField("preview_reset_time", None),
+        ShortField("reserved1", 0)
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+
+class AccessControlRow2(Packet):
+    name = "AccessControlRow2"
+    fields_desc = [
+        BitField("set_ctrl", 0, 2),
+        BitField("row_part_id", 0, 3),
+        BitField("test", 0, 1),
+        BitField("row_key", 0, 10),
+
+        StrFixedLenField("ipv6_dst_addr_start_bytes", None, 12),
+        StrFixedLenField("reserved2", None, 10)
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+
+class DownstreamIgmpMulticastTci(Packet):
+    name = "DownstreamIgmpMulticastTci"
+    fields_desc = [
+        ByteField("ctrl_type", None),
+        ShortField("tci", None)
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+
+class MulticastOperationsProfile(EntityClass):
+    class_id = 309
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC},
+            range_check=lambda x: x != 0 and x != OmciNullPointer),
+        ECA(ByteField("igmp_version", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: x in [1, 2, 3, 16, 17]),
+        ECA(ByteField("igmp_function", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 2),
+        ECA(ByteField("immediate_leave", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("us_igmp_tci", None), {AA.R, AA.W, AA.SBC}, optional=True),
+        ECA(ByteField("us_igmp_tag_ctrl", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 3, optional=True),
+        ECA(IntField("us_igmp_rate", None), {AA.R, AA.W, AA.SBC}, optional=True),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "dynamic_access_control_list_table", None, 24), {AA.R, AA.W}),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "static_access_control_list_table", None, 24), {AA.R, AA.W}),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField("lost_groups_list_table", None, 10), {AA.R}),
+        ECA(ByteField("robustness", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("querier_ip", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("query_interval", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("querier_max_response_time", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("last_member_response_time", 10), {AA.R, AA.W}),
+        ECA(ByteField("unauthorized_join_behaviour", None), {AA.R, AA.W}),
+        ECA(StrFixedLenField("ds_igmp_mcast_tci", None, 3), {AA.R, AA.W, AA.SBC}, optional=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Set, OP.Get, OP.GetNext}
+    optional_operations = {OP.SetTable}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Lost multicast group',
+    }
+
+
+class MulticastServicePackage(Packet):
+    name = "MulticastServicePackage"
+    fields_desc = [
+        BitField("set_ctrl", 0, 2),
+        BitField("reserved0", 0, 4),
+        BitField("row_key", 0, 10),
+
+        ShortField("vid_uni", None),
+        ShortField("max_simultaneous_groups", None),
+        IntField("max_multicast_bw", None),
+        ShortField("mcast_operations_profile_pointer", None),
+        StrFixedLenField("reserved1", None, 8)
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+
+class AllowedPreviewGroupsRow0(Packet):
+    name = "AllowedPreviewGroupsRow0"
+    fields_desc = [
+        BitField("set_ctrl", 0, 2),
+        BitField("row_part_id", 0, 3),
+        BitField("reserved0", 0, 1),
+        BitField("row_key", 0, 10),
+
+        StrFixedLenField("ipv6_pad", 0, 12),
+        IPField("src_ip", None),
+        ShortField("vlan_id_ani", None),
+        ShortField("vlan_id_uni", None)
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+
+class AllowedPreviewGroupsRow1(Packet):
+    name = "AllowedPreviewGroupsRow1"
+    fields_desc = [
+        BitField("set_ctrl", 0, 2),
+        BitField("row_part_id", 0, 3),
+        BitField("reserved0", 0, 1),
+        BitField("row_key", 0, 10),
+
+        StrFixedLenField("ipv6_pad", 0, 12),
+        IPField("dst_ip", None),
+        ShortField("duration", None),
+        ShortField("time_left", None)
+    ]
+
+    def to_json(self):
+        return json.dumps(self.fields, separators=(',', ':'))
+
+
+class MulticastSubscriberConfigInfo(EntityClass):
+    class_id = 310
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("me_type", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ShortField("mcast_operations_profile_pointer", None),
+            {AA.R, AA.W, AA.SBC}),
+        ECA(ShortField("max_simultaneous_groups", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("max_multicast_bandwidth", None), {AA.R, AA.W, AA.SBC}),
+        ECA(ByteField("bandwidth_enforcement", None), {AA.R, AA.W, AA.SBC},
+            range_check=lambda x: 0 <= x <= 1),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "multicast_service_package_table", None, 20), {AA.R, AA.W}),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "allowed_preview_groups_table", None, 22), {AA.R, AA.W}),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Set, OP.Get, OP.GetNext,
+                            OP.SetTable}
+
+
+class VirtualEthernetInterfacePt(EntityClass):
+    class_id = 329
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: x != 0 and x != OmciNullPointer),
+        ECA(ByteField("administrative_state", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("operational_state", None), {AA.R}, avc=True,
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(StrFixedLenField(
+            "interdomain_name", None, 25), {AA.R, AA.W}, optional=True),
+        ECA(ShortField("tcp_udp_pointer", None), {AA.R, AA.W}, optional=True),
+        ECA(ShortField("iana_assigned_port", None), {AA.R}),
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        0: 'Connecting function fail',
+    }
+
+
+class Omci(EntityClass):
+    class_id = 287
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R},
+            range_check=lambda x: x == 0),
+
+        # TODO: Can this be expressed better in SCAPY, probably not?
+        # On the initial, Get request for either the me_type or message_type
+        # attributes, you will receive a 4 octet value (big endian) that is
+        # the number of octets to 'get-next' to fully load the desired
+        # attribute.  For a basic OMCI formatted message, that will be 29
+        # octets per get-request.
+        #
+        # For the me_type_table, these are 16-bit values (ME Class IDs)
+        #
+        # For the message_type_table, these are 8-bit values (Actions)
+
+        ECA(FieldListField("me_type_table", None, ByteField('', 0),
+                           count_from=lambda _: 29), {AA.R}),
+        ECA(FieldListField("message_type_table", None, ByteField('', 0),
+                           count_from=lambda _: 29), {AA.R}),
+    ]
+    mandatory_operations = {OP.Get, OP.GetNext}
+
+
+class EnhSecurityControl(EntityClass):
+    class_id = 332
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(BitField("olt_crypto_capabilities", None, 16*8), {AA.W}),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "olt_random_challenge_table", None, 17), {AA.R, AA.W}),
+        ECA(ByteField("olt_challenge_status", 0), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("onu_selected_crypto_capabilities", None), {AA.R}),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "onu_random_challenge_table", None, 16), {AA.R}, avc=True),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "onu_authentication_result_table", None, 16), {AA.R}, avc=True),
+        # TODO: need to make table and add column data
+        ECA(StrFixedLenField(
+            "olt_authentication_result_table", None, 17), {AA.W}),
+        ECA(ByteField("olt_result_status", None), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("onu_authentication_status", None), {AA.R}, avc=True,
+            range_check=lambda x: 0 <= x <= 5),
+        ECA(StrFixedLenField(
+            "master_session_key_name", None, 16), {AA.R}),
+        ECA(StrFixedLenField(
+            "broadcast_key_table", None, 18), {AA.R, AA.W}),
+        ECA(ShortField("effective_key_length", None), {AA.R}),
+
+    ]
+    mandatory_operations = {OP.Set, OP.Get, OP.GetNext}
+    notifications = {OP.AttributeValueChange}
+
+
+class EthernetPMMonitoringHistoryData(EntityClass):
+    class_id = 24
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("fcs_errors", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("excessive_collision_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("late_collision_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("frames_too_long", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("buffer_overflows_on_rx", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("buffer_overflows_on_tx", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("single_collision_frame_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("multiple_collisions_frame_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("sqe_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("deferred_tx_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("internal_mac_tx_error_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("carrier_sense_error_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("alignment_error_counter", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("internal_mac_rx_error_counter", None), {AA.R}, tca=True, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set, OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'FCS errors',
+        1: 'Excessive collision counter',
+        2: 'Late collision counter',
+        3: 'Frames too long',
+        4: 'Buffer overflows on receive',
+        5: 'Buffer overflows on transmit',
+        6: 'Single collision frame counter',
+        7: 'Multiple collision frame counter',
+        8: 'SQE counter',
+        9: 'Deferred transmission counter',
+        10: 'Internal MAC transmit error counter',
+        11: 'Carrier sense error counter',
+        12: 'Alignment error counter',
+        13: 'Internal MAC receive error counter',
+    }
+
+
+class FecPerformanceMonitoringHistoryData(EntityClass):
+    class_id = 312
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("corrected_bytes", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("corrected_code_words", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("uncorrectable_code_words", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("total_code_words", None), {AA.R}, counter=True),
+        ECA(ShortField("fec_seconds", None), {AA.R}, tca=True, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set, OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Corrected bytes',
+        1: 'Corrected code words',
+        2: 'Uncorrectable code words',
+        4: 'FEC seconds',
+    }
+
+
+class EthernetFrameDownstreamPerformanceMonitoringHistoryData(EntityClass):
+    class_id = 321
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("drop_events", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("octets", None), {AA.R}, counter=True),
+        ECA(IntField("packets", None), {AA.R}, counter=True),
+        ECA(IntField("broadcast_packets", None), {AA.R}, counter=True),
+        ECA(IntField("multicast_packets", None), {AA.R}, counter=True),
+        ECA(IntField("crc_errored_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("undersize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("oversize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("64_octets", None), {AA.R}, counter=True),
+        ECA(IntField("65_to_127_octets", None), {AA.R}, counter=True),
+        ECA(IntField("128_to_255_octets", None), {AA.R}, counter=True),
+        ECA(IntField("256_to_511_octets", None), {AA.R}, counter=True),
+        ECA(IntField("512_to_1023_octets", None), {AA.R}, counter=True),
+        ECA(IntField("1024_to_1518_octets", None), {AA.R}, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set, OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Drop events',
+        1: 'CRC errored packets',
+        2: 'Undersize packets',
+        3: 'Oversize packets',
+    }
+
+
+class EthernetFrameUpstreamPerformanceMonitoringHistoryData(EntityClass):
+    class_id = 322
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("drop_events", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("octets", None), {AA.R}, counter=True),
+        ECA(IntField("packets", None), {AA.R}, counter=True),
+        ECA(IntField("broadcast_packets", None), {AA.R}, counter=True),
+        ECA(IntField("multicast_packets", None), {AA.R}, counter=True),
+        ECA(IntField("crc_errored_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("undersize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("oversize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("64_octets", None), {AA.R}, counter=True),
+        ECA(IntField("65_to_127_octets", None), {AA.R}, counter=True),
+        ECA(IntField("128_to_255_octets", None), {AA.R}, counter=True),
+        ECA(IntField("256_to_511_octets", None), {AA.R}, counter=True),
+        ECA(IntField("512_to_1023_octets", None), {AA.R}, counter=True),
+        ECA(IntField("1024_to_1518_octets", None), {AA.R}, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set, OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Drop events',
+        1: 'CRC errored packets',
+        2: 'Undersize packets',
+        3: 'Oversize packets',
+    }
+
+
+class VeipUni(EntityClass):
+    class_id = 329
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R}),
+        ECA(ByteField("administrative_state", 1), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1),
+        ECA(ByteField("operational_state", 1), {AA.R, AA.W},
+            range_check=lambda x: 0 <= x <= 1, optional=True, avc=True),
+        ECA(StrFixedLenField("interdomain_name", None, 25), {AA.R, AA.W},
+            optional=True),
+        ECA(ShortField("tcp_udp_pointer", None), {AA.R, AA.W}, optional=True),
+        ECA(ShortField("iana_assigned_port", 0xFFFF), {AA.R})
+    ]
+    mandatory_operations = {OP.Get, OP.Set}
+    notifications = {OP.AttributeValueChange, OP.AlarmNotification}
+    alarms = {
+        0: 'Connecting function fail'
+    }
+
+
+class EthernetFrameExtendedPerformanceMonitoring(EntityClass):
+    class_id = 334
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        # 2-octet field -> Threshold data 1/2 ID
+        # 2-octet field -> Parent ME Class
+        # 2-octet field -> Parent ME Instance
+        # 2-octet field -> Accumulation disable
+        # 2-octet field -> TCA Disable
+        # 2-octet field -> Control fields bitmap
+        # 2-octet field -> TCI
+        # 2-octet field -> Reserved
+        ECA(FieldListField("control_block", None, ShortField('', 0),
+                           count_from=lambda _: 8), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("drop_events", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("octets", None), {AA.R}, counter=True),
+        ECA(IntField("packets", None), {AA.R}, counter=True),
+        ECA(IntField("broadcast_packets", None), {AA.R}, counter=True),
+        ECA(IntField("multicast_packets", None), {AA.R}, counter=True),
+        ECA(IntField("crc_errored_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("undersize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("oversize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("64_octets", None), {AA.R}, counter=True),
+        ECA(IntField("65_to_127_octets", None), {AA.R}, counter=True),
+        ECA(IntField("128_to_255_octets", None), {AA.R}, counter=True),
+        ECA(IntField("256_to_511_octets", None), {AA.R}, counter=True),
+        ECA(IntField("512_to_1023_octets", None), {AA.R}, counter=True),
+        ECA(IntField("1024_to_1518_octets", None), {AA.R}, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    optional_operations = {OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Drop events',
+        1: 'CRC errored packets',
+        2: 'Undersize packets',
+        3: 'Oversize packets',
+    }
+
+
+class EthernetFrameExtendedPerformanceMonitoring64Bit(EntityClass):
+    class_id = 426
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        # 2-octet field -> Threshold data 1/2 ID
+        # 2-octet field -> Parent ME Class
+        # 2-octet field -> Parent ME Instance
+        # 2-octet field -> Accumulation disable
+        # 2-octet field -> TCA Disable
+        # 2-octet field -> Control fields bitmap
+        # 2-octet field -> TCI
+        # 2-octet field -> Reserved
+        ECA(FieldListField("control_block", None, ShortField('', 0),
+                           count_from=lambda _: 8), {AA.R, AA.W, AA.SBC}),
+        ECA(LongField("drop_events", None), {AA.R}, tca=True, counter=True),
+        ECA(LongField("octets", None), {AA.R}, counter=True),
+        ECA(LongField("packets", None), {AA.R}, counter=True),
+        ECA(LongField("broadcast_packets", None), {AA.R}, counter=True),
+        ECA(LongField("multicast_packets", None), {AA.R}, counter=True),
+        ECA(LongField("crc_errored_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(LongField("undersize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(LongField("oversize_packets", None), {AA.R}, tca=True, counter=True),
+        ECA(LongField("64_octets", None), {AA.R}, counter=True),
+        ECA(LongField("65_to_127_octets", None), {AA.R}, counter=True),
+        ECA(LongField("128_to_255_octets", None), {AA.R}, counter=True),
+        ECA(LongField("256_to_511_octets", None), {AA.R}, counter=True),
+        ECA(LongField("512_to_1023_octets", None), {AA.R}, counter=True),
+        ECA(LongField("1024_to_1518_octets", None), {AA.R}, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    optional_operations = {OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        0: 'Drop events',
+        1: 'CRC errored packets',
+        2: 'Undersize packets',
+        3: 'Oversize packets',
+    }
+
+
+class GemPortNetworkCtpMonitoringHistoryData(EntityClass):
+    class_id = 341
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("transmitted_gem_frames", None), {AA.R}, counter=True),
+        ECA(IntField("received_gem_frames", None), {AA.R}, counter=True),
+        ECA(LongField("received_payload_bytes", None), {AA.R}, counter=True),
+        ECA(LongField("transmitted_payload_bytes", None), {AA.R}, counter=True),
+        ECA(IntField("encryption_key_errors", None), {AA.R}, tca=True, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set, OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        1: 'Encryption key errors',
+    }
+
+
+class XgPonTcPerformanceMonitoringHistoryData(EntityClass):
+    class_id = 344
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("psbd_hec_error_count", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("xgtc_hec_error_count", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("unknown_profile_count", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("transmitted_xgem_frames", None), {AA.R}, counter=True),
+        ECA(IntField("fragment_xgem_frames", None), {AA.R}, counter=True),
+        ECA(IntField("xgem_hec_lost_words_count", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("xgem_key_errors", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("xgem_hec_error_count", None), {AA.R}, tca=True, counter=True)
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    optional_operations = {OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        1: 'PSBd HEC error count',
+        2: 'XGTC HEC error count',
+        3: 'Unknown profile count',
+        4: 'XGEM HEC loss count',
+        5: 'XGEM key errors',
+        6: 'XGEM HEC error count',
+    }
+
+
+class XgPonDownstreamPerformanceMonitoringHistoryData(EntityClass):
+    class_id = 345
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R},),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("ploam_mic_error_count", None), {AA.R}, tca=True, counter=True),
+        ECA(IntField("downstream_ploam_messages_count", None), {AA.R}, counter=True),
+        ECA(IntField("profile_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("ranging_time_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("deactivate_onu_id_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("disable_serial_number_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("request_registration_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("assign_alloc_id_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("key_control_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("sleep_allow_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("baseline_omci_messages_received_count", None), {AA.R}, counter=True),
+        ECA(IntField("extended_omci_messages_received_count", None), {AA.R}, counter=True),
+        ECA(IntField("assign_onu_id_messages_received", None), {AA.R}, counter=True),
+        ECA(IntField("omci_mic_error_count", None), {AA.R}, tca=True, counter=True),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    optional_operations = {OP.GetCurrentData}
+    notifications = {OP.AlarmNotification}
+    alarms = {
+        1: 'PLOAM MIC error count',
+        2: 'OMCI MIC error count',
+    }
+
+
+class XgPonUpstreamPerformanceMonitoringHistoryData(EntityClass):
+    class_id = 346
+    hidden = True
+    attributes = [
+        ECA(ShortField("managed_entity_id", None), {AA.R, AA.SBC}),
+        ECA(ByteField("interval_end_time", None), {AA.R}),
+        ECA(ShortField("threshold_data_1_2_id", None), {AA.R, AA.W, AA.SBC}),
+        ECA(IntField("upstream_ploam_message_count", None), {AA.R}, counter=True),
+        ECA(IntField("serial_number_onu_message_count", None), {AA.R}, counter=True),
+        ECA(IntField("registration_message_count", None), {AA.R}, counter=True),
+        ECA(IntField("key_report_message_count", None), {AA.R}, counter=True),
+        ECA(IntField("acknowledge_message_count", None), {AA.R}, counter=True),
+        ECA(IntField("sleep_request_message_count", None), {AA.R}, counter=True),
+    ]
+    mandatory_operations = {OP.Create, OP.Delete, OP.Get, OP.Set}
+    optional_operations = {OP.GetCurrentData}
+
+
+# entity class lookup table from entity_class values
+entity_classes_name_map = dict(
+    inspect.getmembers(sys.modules[__name__],
+    lambda o: inspect.isclass(o) and \
+              issubclass(o, EntityClass) and \
+              o is not EntityClass)
+)
+
+entity_classes = [c for c in entity_classes_name_map.itervalues()]
+entity_id_to_class_map = dict((c.class_id, c) for c in entity_classes)