diff --git a/base_node.py b/base_node.py
new file mode 100644
index 0000000..03c7555
--- /dev/null
+++ b/base_node.py
@@ -0,0 +1,218 @@
+
+# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+#
+# Copyright (C) 2014 Regents of the University of California.
+# Author: Adeola Bannis <thecodemaiden@gmail.com>
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# A copy of the GNU General Public License is in the file COPYING.
+import logging
+import time
+import sys
+import random
+
+from pyndn import Name, Face, Interest, Data, ThreadsafeFace
+from pyndn.security import KeyChain
+from pyndn.security.identity import IdentityManager, BasicIdentityStorage
+from pyndn.security.security_exception import SecurityException
+    
+
+from collections import namedtuple
+
+try:
+    import asyncio
+except ImportError:
+    import trollius as asyncio
+
+Command = namedtuple('Command', ['suffix', 'function', 'keywords', 'isSigned'])
+
+class BaseNode(object):
+    """
+    This class contains methods/attributes common to both node and controller.
+    
+    """
+    def __init__(self):
+        """
+        Initialize the network and security classes for the node
+        """
+        super(BaseNode, self).__init__()
+
+
+        self._identityStorage = BasicIdentityStorage()
+        self._identityManager = IdentityManager(self._identityStorage)
+        
+
+        # hopefully there is some private/public key pair available
+        self._keyChain = KeyChain(self._identityManager)
+
+        self._registrationFailures = 0
+        self._prepareLogging()
+
+        self._setupComplete = False
+        self._instanceSerial = None
+
+        # waiting devices register this prefix and respond to discovery
+        # or configuration interest
+        self._bootstrapPrefix = Name('/home/controller/bootstrap')
+
+    def getSerial(self):
+        """
+         Since you may wish to run two nodes on a Raspberry Pi, each
+         node will generate a unique serial number each time it starts up.
+        """
+        if self._instanceSerial is None:
+            prefixLen = 4
+            prefix = ''
+            for i in range(prefixLen):
+                prefix += (chr(random.randint(0,0xff)))
+            suffix = self.getDeviceSerial().lstrip('0')
+            self._instanceSerial = '-'.join([prefix.encode('hex'), suffix])
+        return self._instanceSerial
+
+##
+# Logging
+##
+    def _prepareLogging(self):
+        self.log = logging.getLogger(str(self.__class__))
+        self.log.setLevel(logging.DEBUG)
+        logFormat = "%(asctime)-15s %(name)-20s %(funcName)-20s (%(levelname)-8s):\n\t%(message)s"
+        self._console = logging.StreamHandler()
+        self._console.setFormatter(logging.Formatter(logFormat))
+        self._console.setLevel(logging.INFO)
+        # without this, a lot of ThreadsafeFace errors get swallowed up
+        logging.getLogger("trollius").addHandler(self._console)
+        self.log.addHandler(self._console)
+
+    def setLogLevel(self, level):
+        """
+        Set the log level that will be output to standard error
+        :param level: A log level constant defined in the logging module (e.g. logging.INFO) 
+        """
+        self._console.setLevel(level)
+
+    def getLogger(self):
+        """
+        :return: The logger associated with this node
+        :rtype: logging.Logger
+        """
+        return self.log
+
+###
+# Startup and shutdown
+###
+    def beforeLoopStart(self):
+        """
+        Called before the event loop starts.
+        """
+        pass
+
+    def getDefaultCertificateName(self):
+        try:
+            certName = self._identityStorage.getDefaultCertificateNameForIdentity( 
+                self._identityManager.getDefaultIdentity())
+        except SecurityException:
+            certName = self._keyChain.getDefaultCertificateName()
+
+        return certName
+
+    def start(self):
+        """
+        Begins the event loop. After this, the node's Face is set up and it can
+        send/receive interests+data
+        """
+        self.log.info("Starting up")
+        self.loop = asyncio.get_event_loop()
+        self.face = ThreadsafeFace(self.loop, '')
+        self.face.setCommandSigningInfo(self._keyChain, self.getDefaultCertificateName())
+        self._keyChain.setFace(self.face)
+
+        self._isStopped = False
+        self.face.stopWhen(lambda:self._isStopped)
+        self.beforeLoopStart()
+        
+        try:
+            self.loop.run_forever()
+        except KeyboardInterrupt:
+            pass
+        except Exception as e:
+            self.log.exception(e, exc_info=True)
+        finally:
+            self._isStopped = True
+
+    def stop(self):
+        """
+        Stops the node, taking it off the network
+        """
+        self.log.info("Shutting down")
+        self._isStopped = True 
+        
+###
+# Data handling
+###
+    def signData(self, data):
+        """
+        Sign the data with our network certificate
+        :param pyndn.Data data: The data to sign
+        """
+        self._keyChain.sign(data, self.getDefaultCertificateName())
+
+    def sendData(self, data, transport, sign=True):
+        """
+        Reply to an interest with a data packet, optionally signing it.
+        :param pyndn.Data data: The response data packet
+        :param pyndn.Transport transport: The transport to send the data through. This is 
+            obtained from an incoming interest handler
+        :param boolean sign: (optional, default=True) Whether the response must be signed. 
+        """
+        if sign:
+            self.signData(data)
+        transport.send(data.wireEncode().buf())
+
+###
+# 
+# 
+##
+    def onRegisterFailed(self, prefix):
+        """
+        Called when the node cannot register its name with the forwarder
+        :param pyndn.Name prefix: The network name that failed registration
+        """
+        if self._registrationFailures < 5:
+            self._registrationFailures += 1
+            self.log.warn("Could not register {}, retry: {}/{}".format(prefix.toUri(), self._registrationFailures, 5)) 
+            self.face.registerPrefix(self.prefix, self._onCommandReceived, self.onRegisterFailed)
+        else:
+            self.log.critical("Could not register device prefix, ABORTING")
+            self._isStopped = True
+
+    def verificationFailed(self, dataOrInterest):
+        """
+        Called when verification of a data packet or command interest fails.
+        :param pyndn.Data or pyndn.Interest: The packet that could not be verified
+        """
+        self.log.info("Received invalid" + dataOrInterest.getName().toUri())
+
+    @staticmethod
+    def getDeviceSerial():
+        """
+        Find and return the serial number of the Raspberry Pi. Provided in case
+        you wish to distinguish data from nodes with the same name by serial.
+        :return: The serial number extracted from device information in /proc/cpuinfo
+        :rtype: str
+        """
+        with open('/proc/cpuinfo') as f:
+            for line in f:
+                if line.startswith('Serial'):
+                    return line.split(':')[1].strip()
+
