Finished initial support of Tech Profiles
and fixes for OLT enable/disable since xPON has been removed

Change-Id: I09530f67ba0c2cc7169c5dbaf4aac8729a757c92
diff --git a/voltha/adapters/adtran_olt/adtran_device_handler.py b/voltha/adapters/adtran_olt/adtran_device_handler.py
index 3b80acb..c67fb40 100644
--- a/voltha/adapters/adtran_olt/adtran_device_handler.py
+++ b/voltha/adapters/adtran_olt/adtran_device_handler.py
@@ -917,7 +917,8 @@
         # Remove the peer references from this device
         self.adapter_agent.delete_all_peer_references(self.device_id)
 
-        # Remove the logical device
+        # Remove the logical device to clear out logical device ports for any
+        # previously activated ONUs
         self._delete_logical_device()
 
         # Set all ports to disabled
@@ -1022,12 +1023,9 @@
         # Reenable all child devices
         self.adapter_agent.update_child_devices_state(device.id,
                                                       admin_state=AdminState.ENABLED)
-
-        # Re-subscribe for ONU detection
-        # self.adapter_agent.register_for_onu_detect_state(self.device.id)
-
-        # TODO:
-        # 1) Restart health check / pings
+        # Schedule the heartbeat for the device
+        self.log.debug('starting-heartbeat')
+        self.start_heartbeat(delay=5)
 
         self.log.info('re-enabled', device_id=device.id)
 
diff --git a/voltha/adapters/adtran_olt/adtran_olt_handler.py b/voltha/adapters/adtran_olt/adtran_olt_handler.py
index 8a88ea1..3cb68e5 100644
--- a/voltha/adapters/adtran_olt/adtran_olt_handler.py
+++ b/voltha/adapters/adtran_olt/adtran_olt_handler.py
@@ -620,6 +620,11 @@
         self._zmq_shutdown()
         self._pio_exception_map = []
 
+        # Remove any UNI ports that were created for any activated ONUs
+        uni_ports = self.adapter_agent.get_ports(self.device_id, Port.ETHERNET_UNI)
+        for uni_port in uni_ports:
+            self.adapter_agent.delete_port(self.device_id, uni_port)
+
         super(AdtranOltHandler, self).disable()
 
     def reenable(self, done_deferred=None):
diff --git a/voltha/adapters/adtran_olt/flow/evc_map.py b/voltha/adapters/adtran_olt/flow/evc_map.py
index 5f0b227..f9d81ef 100644
--- a/voltha/adapters/adtran_olt/flow/evc_map.py
+++ b/voltha/adapters/adtran_olt/flow/evc_map.py
@@ -732,21 +732,25 @@
         returnValue(results)
 
     def _shaper_install_xml(self, name, bandwidth):
-        xml = '<adtn-shaper:shapers xmlns:adtn-shaper="http://www.adtran.com/ns/yang/adtran-traffic-shapers" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">' + \
-              ' <adtn-shaper:shaper nc:operation="create">'
-        xml += '  <adtn-shaper:name>{}</adtn-shaper:name>'.format(name)
-        xml += '  <adtn-shaper:enabled>true</adtn-shaper:enabled>'
-        xml += '  <adtn-shaper:rate>{}</adtn-shaper:rate>'.format(bandwidth)
-        xml += '  <adtn-shaper-evc-map:evc-map xmlns:adtn-shaper-evc-map="http://www.adtran.com/ns/yang/adtran-traffic-shaper-evc-maps">{}</adtn-shaper-evc-map:evc-map>'.format(self.name)
-        xml += ' </adtn-shaper:shaper>'
+        xml = '<adtn-shaper:shapers xmlns:adtn-shaper="http://www.adtran.com/ns/yang/adtran-traffic-shapers" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="merge">'
+        for onu_id, gem_ids_and_vid in self._gem_ids_and_vid.iteritems():
+            for gem_id in gem_ids_and_vid[0]:
+                xml += ' <adtn-shaper:shaper>'
+                xml += '  <adtn-shaper:name>{}.{}.{}</adtn-shaper:name>'.format(name, onu_id, gem_id)
+                xml += '  <adtn-shaper:enabled>true</adtn-shaper:enabled>'
+                xml += '  <adtn-shaper:rate>{}</adtn-shaper:rate>'.format(bandwidth)
+                xml += '  <adtn-shaper-evc-map:evc-map xmlns:adtn-shaper-evc-map="http://www.adtran.com/ns/yang/adtran-traffic-shaper-evc-maps">{}.{}.{}</adtn-shaper-evc-map:evc-map>'.format(self.name, onu_id, gem_id)
+                xml += ' </adtn-shaper:shaper>'
         xml += '</adtn-shaper:shapers>'
         return xml
 
     def _shaper_remove_xml(self, name):
-        xml = '<adtn-shaper:shapers xmlns:adtn-shaper="http://www.adtran.com/ns/yang/adtran-traffic-shapers" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">' + \
-              ' <adtn-shaper:shaper nc:operation="delete">'
-        xml += '  <adtn-shaper:name>{}</adtn-shaper:name>'.format(self.name)
-        xml += ' </adtn-shaper:shaper>'
+        xml = '<adtn-shaper:shapers xmlns:adtn-shaper="http://www.adtran.com/ns/yang/adtran-traffic-shapers" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete">'
+        for onu_id, gem_ids_and_vid in self._gem_ids_and_vid.iteritems():
+            for gem_id in gem_ids_and_vid[0]:
+                xml += ' <adtn-shaper:shaper >'
+                xml += '  <adtn-shaper:name>{}.{}.{}</adtn-shaper:name>'.format(name, onu_id, gem_id)
+                xml += ' </adtn-shaper:shaper>'
         xml += '</adtn-shaper:shapers>'
         return xml
 
diff --git a/voltha/adapters/adtran_olt/resources/adtran_olt_resource_manager.py b/voltha/adapters/adtran_olt/resources/adtran_olt_resource_manager.py
index c6ce41b..074c07e 100644
--- a/voltha/adapters/adtran_olt/resources/adtran_olt_resource_manager.py
+++ b/voltha/adapters/adtran_olt/resources/adtran_olt_resource_manager.py
@@ -70,7 +70,8 @@
 
     def __del__(self):
         self.log.info("clearing-device-resource-pool")
-        self.resource_mgr.clear_device_resource_pool()
+        for key, resource_mgr in self.resource_mgrs.iteritems():
+            resource_mgr.clear_device_resource_pool()
 
     def get_onu_id(self, pon_intf_id):
         onu_id = self.resource_mgr.get_resource_id(pon_intf_id,
diff --git a/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py b/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py
index 14efbf7..965e6ca 100644
--- a/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py
+++ b/voltha/adapters/adtran_olt/resources/adtran_resource_manager.py
@@ -75,6 +75,10 @@
                 pon_intf_id=pon_id,
                 resource_type=PONResourceManager.GEMPORT_ID,
             )
+            self.clear_resource_id_pool(
+                pon_intf_id=pon_id,
+                resource_type=PONResourceManager.FLOW_ID,
+            )
 
     def init_resource_id_pool(self, pon_intf_id, resource_type, start_idx=None,
                               end_idx=None, resource_map=None):
diff --git a/voltha/adapters/adtran_onu/adtran_onu_handler.py b/voltha/adapters/adtran_onu/adtran_onu_handler.py
index ccc0f7d..aa05e3e 100644
--- a/voltha/adapters/adtran_onu/adtran_onu_handler.py
+++ b/voltha/adapters/adtran_onu/adtran_onu_handler.py
@@ -391,9 +391,9 @@
         bidirectional_ids = upstream_ids & downstream_ids
 
         gem_port_types = {     # Keys are the 'direction' attribute value, value is list of GEM attributes
-            1: [upstream[gid] for gid in upstream_ids - bidirectional_ids],
-            2: [downstream[gid] for gid in downstream_ids - bidirectional_ids],
-            3: [upstream[gid] for gid in bidirectional_ids]
+            OnuGemPort.UPSTREAM: [upstream[gid] for gid in upstream_ids - bidirectional_ids],
+            OnuGemPort.DOWNSTREAM: [downstream[gid] for gid in downstream_ids - bidirectional_ids],
+            OnuGemPort.BIDIRECTIONAL: [upstream[gid] for gid in bidirectional_ids]
         }
         for direction, gem_list in gem_port_types.items():
             for gem in gem_list:
@@ -405,10 +405,10 @@
                     'max-q-size': gem['max_q_size'],
                     'pbit-map': gem['pbit_map'],
                     'priority-q': gem['priority_q'],
-                    'scheduling_policy': gem['scheduling_policy'],
+                    'scheduling-policy': gem['scheduling_policy'],
                     'weight': gem['weight'],
                     'uni-id': uni_id,
-                    'discard_config': {
+                    'discard-config': {
                         'max-probability': gem['discard_config']['max_probability'],
                         'max-threshold': gem['discard_config']['max_threshold'],
                         'min-threshold': gem['discard_config']['min_threshold'],
@@ -456,7 +456,7 @@
                 def success(_results):
                     self.log.info("tech-profile-config-done-successfully")
                     device = self.adapter_agent.get_device(self.device_id)
-                    device.reason = 'Tech Profile config Success'
+                    device.reason = ''
                     self.adapter_agent.update_device(device)
 
                     if tp_path in self._tp_service_specific_task[uni_id]:
diff --git a/voltha/adapters/adtran_onu/omci/adtn_install_flow.py b/voltha/adapters/adtran_onu/omci/adtn_install_flow.py
index 04d9d1f..5d5a2f6 100644
--- a/voltha/adapters/adtran_onu/omci/adtn_install_flow.py
+++ b/voltha/adapters/adtran_onu/omci/adtn_install_flow.py
@@ -73,8 +73,7 @@
         # TODO: Probably need to store many of these in the appropriate object (UNI, PON,...)
         #
         self._ethernet_uni_entity_id = self._handler.uni_ports[0].entity_id
-        self._ieee_mapper_service_profile_entity_id = self._pon.hsi_8021p_mapper_entity_id
-        # self._hsi_mac_bridge_port_ani_entity_id = self._pon.hsi_mac_bridge_port_ani_entity_id
+        self._ieee_mapper_service_profile_entity_id = self._pon.ieee_mapper_service_profile_entity_id
 
         # Next to are specific
         self._mac_bridge_service_profile_entity_id = handler.mac_bridge_service_profile_entity_id
@@ -177,7 +176,7 @@
                     )
 
                     frame = ExtendedVlanTaggingOperationConfigurationDataFrame(
-                        self._mac_bridge_service_profile_entity_id,
+                        self._mac_bridge_service_profile_entity_id + self._uni.mac_bridge_port_num,
                         attributes=attributes
                     ).create()
                     results = yield omci.send(frame)
@@ -186,7 +185,7 @@
                     # TODO: Any of the following needed as well
 
                     # # Delete bridge ani side vlan filter
-                    # msg = VlanTaggingFilterDataFrame(self._hsi_mac_bridge_port_ani_entity_id)
+                    # msg = VlanTaggingFilterDataFrame(self._mac_bridge_port_ani_entity_id)
                     # frame = msg.delete()
                     #
                     # results = yield omci.send(frame)
@@ -194,7 +193,7 @@
                     #
                     # # Re-Create bridge ani side vlan filter
                     # msg = VlanTaggingFilterDataFrame(
-                    #         self._hsi_mac_bridge_port_ani_entity_id,  # Entity ID
+                    #         self._mac_bridge_port_ani_entity_id,  # Entity ID
                     #         vlan_tcis=[vlan_vid],             # VLAN IDs
                     #         forward_operation=0x10
                     # )
@@ -239,7 +238,7 @@
                 #         )
                 # )
                 # msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
-                #         self._mac_bridge_service_profile_entity_id,  # Bridge Entity ID
+                #         self._mac_bridge_service_profile_entity_id + self._uni.mac_bridge_port_num,  # Bridge Entity ID
                 #         attributes=attributes  # See above
                 # )
                 # frame = msg.set()
@@ -260,24 +259,22 @@
                 # TODO: Downstream mode may need to be modified once we work more on the flow rules
 
                 attributes = dict(
-                    input_tpid=0x8100,  # input TPID
+                    input_tpid=0x8100,   # input TPID
                     output_tpid=0x8100,  # output TPID
-                    downstream_mode=0,  # inverse of upstream
+                    downstream_mode=0,   # inverse of upstream
                 )
 
                 msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
-                        self._mac_bridge_service_profile_entity_id,  # Bridge Entity ID
-                        attributes=attributes  # See above
+                        self._mac_bridge_service_profile_entity_id +
+                        self._uni.mac_bridge_port_num,  # Bridge Entity ID
+                        attributes=attributes           # See above
                 )
                 frame = msg.set()
 
                 results = yield omci.send(frame)
                 self.check_status_and_state(results, 'set-extended-vlan-tagging-operation-configuration-data')
 
-
                 attributes = dict(
-
-
                     received_frame_vlan_tagging_operation_table=
                     VlanTaggingOperation(
                         filter_outer_priority=15,  # This entry is not a double-tag rule
@@ -302,8 +299,9 @@
                 )
 
                 msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
-                        self._mac_bridge_service_profile_entity_id,  # Bridge Entity ID
-                        attributes=attributes  # See above
+                        self._mac_bridge_service_profile_entity_id +
+                        self._uni.mac_bridge_port_num,  # Bridge Entity ID
+                        attributes=attributes           # See above
                 )
                 frame = msg.set()
 
diff --git a/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py b/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py
index 0ef7d92..36289bf 100644
--- a/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py
+++ b/voltha/adapters/adtran_onu/omci/adtn_mib_download_task.py
@@ -88,8 +88,8 @@
         #
         # TODO: Probably need to store many of these in the appropriate object (UNI, PON,...)
         #
-        self._ieee_mapper_service_profile_entity_id = self._pon.hsi_8021p_mapper_entity_id
-        self._mac_bridge_port_ani_entity_id = self._pon.hsi_mac_bridge_port_ani_entity_id
+        self._ieee_mapper_service_profile_entity_id = self._pon.ieee_mapper_service_profile_entity_id
+        self._mac_bridge_port_ani_entity_id = self._pon.mac_bridge_port_ani_entity_id
         self._gal_enet_profile_entity_id = self._handler.gal_enet_profile_entity_id
 
         # Next to are specific     TODO: UNI lookups here or uni specific install !!!
@@ -173,18 +173,23 @@
             try:
                 # Lock the UNI ports to prevent any alarms during initial configuration
                 # of the ONU
-                self.strobe_watchdog()
-                # yield self.enable_unis(self._handler.uni_ports, True)
+                for uni_port in self._handler.uni_ports:
+                    self.strobe_watchdog()
 
-                # Provision the initial bridge configuration
-                yield self.perform_initial_bridge_setup()
+                    yield self.enable_uni(uni_port, True)
 
-                # If here, we are done with the generic MIB download
-                device = self._handler.adapter_agent.get_device(self.device_id)
+                    # Provision the initial bridge configuration
+                    yield self.perform_initial_bridge_setup(uni_port)
 
-                device.reason = 'Initial OMCI Download Complete'
-                self._handler.adapter_agent.update_device(device)
-                self.deferred.callback('MIB Download - success')
+                    # And re-enable the UNIs if needed
+                    yield self.enable_uni(uni_port, False)
+
+                    # If here, we are done with the generic MIB download
+                    device = self._handler.adapter_agent.get_device(self.device_id)
+
+                    device.reason = 'Initial OMCI Download Complete'
+                    self._handler.adapter_agent.update_device(device)
+                    self.deferred.callback('MIB Download - success')
 
             except TimeoutError as e:
                 self.deferred.errback(failure.Failure(e))
@@ -195,7 +200,7 @@
             self.deferred.errback(failure.Failure(e))
 
     @inlineCallbacks
-    def perform_initial_bridge_setup(self):
+    def perform_initial_bridge_setup(self, uni_port):
         omci_cc = self._onu_device.omci_cc
         frame = None
 
@@ -231,7 +236,8 @@
             #            - Nothing at this point. When a GEM port is created, this entity will
             #              be updated to reference the GEM Interworking TP
 
-            frame = Ieee8021pMapperServiceProfileFrame(self._ieee_mapper_service_profile_entity_id).create()
+            frame = Ieee8021pMapperServiceProfileFrame(self._ieee_mapper_service_profile_entity_id +
+                                                       uni_port.mac_bridge_port_num).create()
             results = yield omci_cc.send(frame)
             self.check_status_and_state(results, 'create-8021p-mapper-service-profile')
 
@@ -256,7 +262,8 @@
                 # TODO: The PORT number for this port and the UNI port are the same. Correct?
                 port_num=self._pon_port_num,                            # Port ID
                 tp_type=3,                                              # TP Type (IEEE 802.1p mapper service)
-                tp_pointer=self._ieee_mapper_service_profile_entity_id  # TP ID, 8021p mapper ID
+                tp_pointer=self._ieee_mapper_service_profile_entity_id +
+                           uni_port.mac_bridge_port_num                 # TP ID, 8021p mapper ID
             ).create()
             results = yield omci_cc.send(frame)
             self.check_status_and_state(results, 'create-mac-bridge-port-config-data-part-1')
@@ -327,7 +334,7 @@
         returnValue(None)
 
     @inlineCallbacks
-    def enable_unis(self, unis, force_lock):
+    def enable_uni(self, uni, force_lock):
         """
         Lock or unlock one or more UNI ports
 
@@ -335,29 +342,29 @@
         :param force_lock: (boolean) If True, force lock regardless of enabled state
         """
         omci_cc = self._onu_device.omci_cc
-        frame = None
 
-        for uni in unis:
-            ##################################################################
-            #  Lock/Unlock UNI  -  0 to Unlock, 1 to lock
-            #
-            #  EntityID is referenced by:
-            #            - MAC bridge port configuration data for the UNI side
-            #  References:
-            #            - Nothing
-            try:
-                state = 1 if force_lock or not uni.enabled else 0
-                frame = PptpEthernetUniFrame(uni.entity_id,
-                                             attributes=dict(administrative_state=state)).set()
-                results = yield omci_cc.send(frame)
-                self.check_status_and_state(results, 'set-pptp-ethernet-uni-lock-restore')
+        ##################################################################
+        #  Lock/Unlock UNI  -  0 to Unlock, 1 to lock
+        #
+        #  EntityID is referenced by:
+        #            - MAC bridge port configuration data for the UNI side
+        #  References:
+        #            - Nothing
+        try:
+            state = 1 if force_lock or not uni.enabled else 0
 
-            except TimeoutError:
-                self.log.warn('rx-timeout-uni-enable', frame=hexlify(frame))
-                raise
+            frame = PptpEthernetUniFrame(uni.entity_id,
+                                         attributes=dict(administrative_state=state)).set()
 
-            except Exception as e:
-                self.log.exception('omci-failure', e=e)
-                raise
+            results = yield omci_cc.send(frame)
+            self.check_status_and_state(results, 'set-pptp-ethernet-uni-lock-restore')
+
+        except TimeoutError:
+            self.log.warn('rx-timeout-uni-enable', uni_port=uni)
+            raise
+
+        except Exception as e:
+            self.log.exception('omci-failure', e=e)
+            raise
 
         returnValue(None)
diff --git a/voltha/adapters/adtran_onu/omci/adtn_remove_flow.py b/voltha/adapters/adtran_onu/omci/adtn_remove_flow.py
index 53db01a..f0fbf77 100644
--- a/voltha/adapters/adtran_onu/omci/adtn_remove_flow.py
+++ b/voltha/adapters/adtran_onu/omci/adtn_remove_flow.py
@@ -67,10 +67,10 @@
         # self._output_tpid = AdtnRemoveFlowTask.default_tpid
 
         is_upstream = flow_entry.flow_direction in FlowEntry.upstream_flow_types
-        # uni_port = flow_entry.in_port if is_upstream else flow_entry.out_port
+        uni_port = flow_entry.in_port if is_upstream else flow_entry.out_port
         pon_port = flow_entry.out_port if is_upstream else flow_entry.in_port
 
-        # self._uni = handler.uni_port(uni_port)
+        self._uni = handler.uni_port(uni_port)
         self._pon = handler.pon_port(pon_port)
 
         self._vid = OMCI.DEFAULT_UNTAGGED_VLAN
@@ -80,8 +80,8 @@
         #
         # TODO: Probably need to store many of these in the appropriate object (UNI, PON,...)
         #
-        self._ieee_mapper_service_profile_entity_id = self._pon.hsi_8021p_mapper_entity_id
-        self._mac_bridge_port_ani_entity_id = self._pon.hsi_mac_bridge_port_ani_entity_id
+        self._ieee_mapper_service_profile_entity_id = self._pon.ieee_mapper_service_profile_entity_id
+        self._mac_bridge_port_ani_entity_id = self._pon.mac_bridge_port_ani_entity_id
 
         # Next to are specific
         self._mac_bridge_service_profile_entity_id = handler.mac_bridge_service_profile_entity_id
@@ -146,7 +146,9 @@
         """
         Send the commands to configure the flow
         """
-        self.log.info('perform-flow-removall')
+        self.log.info('perform-flow-removal')
+
+        # TODO: This has not been fully implemented
 
         def resources_available():
             return (len(self._handler.uni_ports) > 0 and
@@ -201,8 +203,9 @@
                         )
                 )
                 msg = ExtendedVlanTaggingOperationConfigurationDataFrame(
-                        self._mac_bridge_service_profile_entity_id,  # Bridge Entity ID
-                        attributes=attributes  # See above
+                        self._mac_bridge_service_profile_entity_id +
+                        self._uni.mac_bridge_port_num,  # Bridge Entity ID
+                        attributes=attributes           # See above
                 )
                 frame = msg.set()
                 results = yield omci.send(frame)
diff --git a/voltha/adapters/adtran_onu/omci/adtn_tp_service_specific_task.py b/voltha/adapters/adtran_onu/omci/adtn_tp_service_specific_task.py
index 2d7ea69..f48f370 100644
--- a/voltha/adapters/adtran_onu/omci/adtn_tp_service_specific_task.py
+++ b/voltha/adapters/adtran_onu/omci/adtn_tp_service_specific_task.py
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import structlog
 from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks, TimeoutError, failure, returnValue
 from voltha.extensions.omci.omci_me import *
@@ -83,8 +82,8 @@
         #             IDs set to None are discovered/set
 
         self._mac_bridge_service_profile_entity_id = handler.mac_bridge_service_profile_entity_id
-        self._ieee_mapper_service_profile_entity_id = pon_port.hsi_8021p_mapper_entity_id
-        self._mac_bridge_port_ani_entity_id = pon_port.hsi_mac_bridge_port_ani_entity_id
+        self._ieee_mapper_service_profile_entity_id = pon_port.ieee_mapper_service_profile_entity_id
+        self._mac_bridge_port_ani_entity_id = pon_port.mac_bridge_port_ani_entity_id
         self._gal_enet_profile_entity_id = handler.gal_enet_profile_entity_id
 
         # Extract the current set of TCONT and GEM Ports from the Handler's pon_port that are
@@ -95,7 +94,7 @@
                         if tcont.uni_id == self._uni_port.uni_id]
 
         self._gem_ports = [gem_port for gem_port in pon_port.gem_ports.itervalues()
-                           if gem_port.uni_id != self._uni_port.uni_id]
+                           if gem_port.uni_id == self._uni_port.uni_id]
 
         self.tcont_me_to_queue_map = dict()
         self.uni_port_to_queue_map = dict()
@@ -371,7 +370,8 @@
                     pass
 
             msg = Ieee8021pMapperServiceProfileFrame(
-                self._ieee_mapper_service_profile_entity_id + self._uni_port.mac_bridge_port_num,  # 802.1p mapper Service Mapper Profile ID
+                self._ieee_mapper_service_profile_entity_id +
+                self._uni_port.mac_bridge_port_num,   # 802.1p mapper Service Mapper Profile ID
                 interwork_tp_pointers=gem_entity_ids  # Interworking TP IDs
             )
             frame = msg.set()
diff --git a/voltha/adapters/adtran_onu/omci/adtn_service_download_task.py b/voltha/adapters/adtran_onu/omci/deprecated/adtn_service_download_task.py
similarity index 99%
rename from voltha/adapters/adtran_onu/omci/adtn_service_download_task.py
rename to voltha/adapters/adtran_onu/omci/deprecated/adtn_service_download_task.py
index 11ce30a..a272e3d 100644
--- a/voltha/adapters/adtran_onu/omci/adtn_service_download_task.py
+++ b/voltha/adapters/adtran_onu/omci/deprecated/adtn_service_download_task.py
@@ -88,7 +88,7 @@
         #
         # TODO: Probably need to store many of these in the appropriate object (UNI, PON,...)
         #
-        self._ieee_mapper_service_profile_entity_id = self._pon.hsi_8021p_mapper_entity_id
+        self._ieee_mapper_service_profile_entity_id = self._pon.ieee_mapper_service_profile_entity_id
         self._gal_enet_profile_entity_id = self._handler.gal_enet_profile_entity_id
 
         # Next to are specific
diff --git a/voltha/adapters/adtran_onu/onu_gem_port.py b/voltha/adapters/adtran_onu/onu_gem_port.py
index 89065ab..4b41038 100644
--- a/voltha/adapters/adtran_onu/onu_gem_port.py
+++ b/voltha/adapters/adtran_onu/onu_gem_port.py
@@ -32,7 +32,9 @@
                  uni_id, entity_id,
                  multicast=False, traffic_class=None, is_mock=False):
         gem_id = gem_data['gemport-id']
+        self.log = structlog.get_logger(device_id=handler.device_id, gem_id=gem_id)
         encryption = gem_data['encryption']
+
         super(OnuGemPort, self).__init__(gem_id, alloc_id, uni_id,
                                          tech_profile_id,
                                          encryption=encryption,
@@ -40,25 +42,113 @@
                                          traffic_class=traffic_class,
                                          handler=handler,
                                          is_mock=is_mock)
-        self._gem_data = gem_data
-        self._entity_id = entity_id
-        self._tcont_entity_id = None
-        self._interworking = False
-        self.uni_id = gem_data['uni-id']
-        self.log = structlog.get_logger(device_id=handler.device_id, gem_id=gem_id)
+        try:
+            self._gem_data = gem_data
+            self._entity_id = entity_id
+            self._tcont_entity_id = None
+            self._interworking = False
+            self.uni_id = gem_data['uni-id']
+            self.direction = gem_data.get('direction', OnuGemPort.BIDIRECTIONAL)
+
+            # IEEE 802.1p Mapper ME (#130) related parameters
+            self._pbit_map = None
+            self.pbit_map = gem_data.get('pbit-map', '0b00000011')
+
+            # Upstream priority queue ME (#277) related parameters
+            self.priority_q = gem_data.get('priority-q', 3)
+
+            self._max_q_size = None
+            self.max_q_size = gem_data.get('max-q-size', 'auto')
+
+            self.weight = gem_data.get('weight', 8)
+
+            self._discard_config = None
+            self.discard_config = gem_data.get('discard-config',  None)
+
+            self._discard_policy = None
+            self.discard_policy = gem_data.get('discard-policy', 'TailDrop')
+
+            # Traffic scheduler ME (#278) related parameters
+            self._scheduling_policy = None
+            self.scheduling_policy = gem_data.get('scheduling-policy', 'WRR')
+
+        except Exception as _e:
+            raise
 
     @property
     def entity_id(self):
         return self._entity_id
 
     @property
+    def discard_config(self):
+        return self._discard_config
+
+    @discard_config.setter
+    def discard_config(self, discard_config):
+        assert isinstance(discard_config, dict), "discard-config not dict"
+        assert 'max-probability' in discard_config, "max-probability missing"
+        assert 'max-threshold' in discard_config, "max-hreshold missing"
+        assert 'min-threshold' in discard_config, "min-threshold missing"
+        self._discard_config = discard_config
+
+    @property
+    def discard_policy(self):
+        self.log.debug('function-entry')
+        return self._discard_policy
+
+    @discard_policy.setter
+    def discard_policy(self, discard_policy):
+        dp = ("TailDrop", "WTailDrop", "RED", "WRED")
+        assert (isinstance(discard_policy, str))
+        assert (discard_policy in dp)
+        self._discard_policy = discard_policy
+
+    @property
+    def max_q_size(self):
+        return self._max_q_size
+
+    @max_q_size.setter
+    def max_q_size(self, max_q_size):
+        if isinstance(max_q_size, str):
+            assert (max_q_size == "auto")
+        else:
+            assert (isinstance(max_q_size, int))
+
+        self._max_q_size = max_q_size
+
+    @property
+    def pbit_map(self):
+        return self._pbit_map
+
+    @pbit_map.setter
+    def pbit_map(self, pbit_map):
+        assert (isinstance(pbit_map, str))
+        assert (len(pbit_map[2:]) == 8)  # Example format of pbit_map: "0b00000101"
+        try:
+            _ = int(pbit_map[2], 2)
+        except ValueError:
+            raise Exception("pbit_map-not-binary-string-{}".format(pbit_map))
+
+        # remove '0b'
+        self._pbit_map = pbit_map[2:]
+
+    @property
+    def scheduling_policy(self):
+        return self._scheduling_policy
+
+    @scheduling_policy.setter
+    def scheduling_policy(self, scheduling_policy):
+        sp = ("WRR", "StrictPriority")
+        assert (isinstance(scheduling_policy, str))
+        assert (scheduling_policy in sp)
+        self._scheduling_policy = scheduling_policy
+
+    @property
     def in_hardware(self):
         return self._tcont_entity_id is not None and self._interworking
 
     @staticmethod
     def create(handler, gem_data, alloc_id, tech_profile_id, uni_id, entity_id):
-        # TODO: Only a minimal amount of info from the 'gem_port' dictionary
-        #       is currently used to create the GEM ports.
         return OnuGemPort(handler, gem_data, alloc_id,
                           tech_profile_id, uni_id, entity_id)
 
diff --git a/voltha/adapters/adtran_onu/pon_port.py b/voltha/adapters/adtran_onu/pon_port.py
index 4f00c0d..f879ccf 100644
--- a/voltha/adapters/adtran_onu/pon_port.py
+++ b/voltha/adapters/adtran_onu/pon_port.py
@@ -43,8 +43,8 @@
 
         # OMCI resources
         # TODO: These could be dynamically chosen (can be most any value)
-        self.hsi_8021p_mapper_entity_id = 0x100
-        self.hsi_mac_bridge_port_ani_entity_id = 0x100
+        self.ieee_mapper_service_profile_entity_id = 0x100
+        self.mac_bridge_port_ani_entity_id = 0x100
 
     def __str__(self):
         return "PonPort"      # TODO: Encode current state