Packet-in channel plumbed thru whole stack

Change-Id: I1df0265139259cc1757f29af19132c5384943c15
diff --git a/voltha/core/adapter_agent.py b/voltha/core/adapter_agent.py
index 83b4e89..2a6c61b 100644
--- a/voltha/core/adapter_agent.py
+++ b/voltha/core/adapter_agent.py
@@ -20,6 +20,7 @@
 from uuid import uuid4
 
 import structlog
+from scapy.packet import Packet
 from twisted.internet.defer import inlineCallbacks, returnValue
 from zope.interface import implementer
 
@@ -251,3 +252,15 @@
     def receive_proxied_message(self, proxy_address, msg):
         topic = self._gen_rx_proxy_address_topic(proxy_address)
         self.event_bus.publish(topic, msg)
+
+    # ~~~~~~~~~~~~~~~~~~ Handling packet-in and packet-out ~~~~~~~~~~~~~~~~~~~~
+
+    def send_packet_in(self, logical_device_id, logical_port_no, packet):
+        self.log.debug('send-packet-in', logical_device_id=logical_device_id,
+                       logical_port_no=logical_port_no, packet=packet)
+
+        if isinstance(packet, Packet):
+            packet = str(packet)
+
+        topic = 'packet-in:' + logical_device_id
+        self.event_bus.publish(topic, (logical_port_no, packet))