Build basic working structure of NDN-HOME
Change-Id: I56cdbac58407192ed9e79ec55f2196c20c2e952d
diff --git a/base_node.py b/base_node.py
index 2393eea..b93bc5d 100644
--- a/base_node.py
+++ b/base_node.py
@@ -17,33 +17,32 @@
# 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.
+"""
+This module defines BaseNode class, which contains methods/attributes common to both end device and controller.
+"""
+
import logging
import time
import sys
-
import random
-from pyndn import Name, Face, Interest, Data, ThreadsafeFace
-from pyndn.security.policy import ConfigPolicyManager
+from pyndn import Name, Face, Interest, Data
+from pyndn.threadsafe_face import ThreadsafeFace
from pyndn.security import KeyChain
from pyndn.security.identity import IdentityManager, BasicIdentityStorage
+from pyndn.security.policy import NoVerifyPolicyManager, ConfigPolicyManager
from pyndn.security.security_exception import SecurityException
-
-from collections import namedtuple
+from access_control_manager import AccessControlManager
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 end device and controller.
-
- """
+
def __init__(self,configFileName):
"""
Initialize the network and security classes for the node
@@ -53,9 +52,12 @@
self._identityStorage = BasicIdentityStorage()
self._identityManager = IdentityManager(self._identityStorage)
- self._policyManager = ConfigPolicyManager(configFileName)
- # hopefully there is some private/public key pair available
+ if configFileName:
+ self._policyManager = ConfigPolicyManager(configFileName)
+ else:
+ self._policyManager = NoVerifyPolicyManager()
+
self._keyChain = KeyChain(self._identityManager,self._policyManager)
self._registrationFailures = 0
@@ -64,10 +66,11 @@
self._setupComplete = False
self._instanceSerial = None
- # waiting devices register this prefix and respond to discovery
- # or configuration interest
self._bootstrapPrefix = '/home/controller/bootstrap'
-
+ self._serviceProfileList = []
+ self._commmandList = []
+ self._protocolList = []
+
def getSerial(self):
"""
Since you may wish to run two nodes on a Raspberry Pi, each
@@ -82,9 +85,99 @@
self._instanceSerial = prefix.encode('hex')
return self._instanceSerial
-##
-# Logging
-##
+ def addServiceProfiles(self,profiles):
+ pass
+
+ def addServices(self,services):
+ pass
+
+ def addProtocols(self,protocols):
+ pass
+
+
+ def beforeLoopStart(self):
+ """
+ Called before the event loop starts.
+ """
+ pass
+
+
+ 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, 'localhost')
+
+ self._keyChain.setFace(self.face)
+ self.beforeLoopStart()
+
+ self.face.setCommandSigningInfo(self._keyChain, self._keyChain.getDefaultCertificateName())
+
+ try:
+ self.loop.run_forever()
+ except Exception as e:
+ self.log.exception(e, exc_info=True)
+
+ def createACK(self):
+ pass
+
+ def createNACK(self):
+ pass
+
+ def signData(self, data):
+ """
+ Sign the data with our network certificate
+ :param pyndn.Data data: The data to sign
+ """
+ pass
+
+ 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())
+
+ """
+ Failure
+
+ """
+
+ 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())
+
+
+
+
+ """
+ Logging
+ """
+
def _prepareLogging(self):
self.log = logging.getLogger(str(self.__class__))
self.log.setLevel(logging.DEBUG)
@@ -110,117 +203,7 @@
"""
return self.log
-###
-# Startup and shutdown
-###
- def beforeLoopStart(self):
- """
- Called before the event loop starts.
- """
- pass
-
- def getKeyChain(self):
- return self._keyChain
- def getDefaultIdentity(self):
- try:
- defaultIdentity = self._identityManager.getDefaultIdentity()
- except SecurityException:
- defaultIdentity = ""
-
- return defaultIdentity
-
-
- def getDefaultCertificateName(self):
- #exception - no certficate, return ''
-
- try:
- certName = self._identityStorage.getDefaultCertificateNameForIdentity(
- self._identityManager.getDefaultIdentity())
- except SecurityException:
- certName = ""
-
- 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._keyChain.setFace(self.face)
-
- self._isStopped = False
- self.face.stopWhen(lambda:self._isStopped)
-
- self.beforeLoopStart()
-
- self.face.setCommandSigningInfo(self._keyChain, self.getDefaultCertificateName())
-
- 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():
@@ -233,6 +216,4 @@
with open('/proc/cpuinfo') as f:
for line in f:
if line.startswith('Serial'):
- return line.split(':')[1].strip()
-
-
+ return line.split(':')[1].strip()
\ No newline at end of file