class BaseNode(object): """ This class contains methods/attributes common to both node and controller. """ def __init__(self, transport = None, conn = None): """ Initialize the network and security classes for the node """ super(BaseNode, self).__init__() self.faceTransport = transport self.faceConn = conn self._identityStorage = BasicIdentityStorage() self._identityManager = IdentityManager(self._identityStorage, FilePrivateKeyStorage()) self._policyManager = IotPolicyManager(self._identityStorage) # hopefully there is some private/public key pair available self._keyChain = KeyChain(self._identityManager, self._policyManager) self._registrationFailures = 0 self._prepareLogging() self._setupComplete = False ## # 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._policyManager.getDeviceIdentity()) except SecurityException as e: # zhehao: in the case of producer's /localhop prefixes, the default key is not defined in ndnsec-public-info.db certName = self._keyChain.createIdentityAndCertificate(self._policyManager.getDeviceIdentity()) #certName = self._keyChain.getDefaultCertificateName() #print(certName.toUri()) 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() if (self.faceTransport == None or self.faceTransport == ''): self.face = ThreadsafeFace(self.loop) else: self.face = ThreadsafeFace(self.loop, self.faceTransport, self.faceConn) self.face.setCommandSigningInfo(self._keyChain, self.getDefaultCertificateName()) self._keyChain.setFace(self.face) self._isStopped = False self.beforeLoopStart() try: self.loop.run_forever() except Exception as e: self.log.exception(exc_info=True) finally: self.stop() def stop(self): """ Stops the node, taking it off the network """ self.log.info("Shutting down") self._isStopped = True self.loop.stop() ### # 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, sign=True): """ Reply to an interest with a data packet, optionally signing it. :param pyndn.Data data: The response data packet :param boolean sign: (optional, default=True) Whether the response must be signed. """ if sign: self.signData(data) self.face.putData(data) ### # # ## 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.faceTransport != None and self.faceConn != None: self.log.warn("Explicit face transport and connectionInfo: Could not register {}; expect a manual or autoreg on the other side.".format(prefix.toUri())) elif 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.info("Prefix registration failed") self.stop() 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 getSerial(): """ 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 """ try: with open('/proc/cpuinfo') as f: for line in f: if line.startswith('Serial'): return line.split(':')[1].strip() except NameError: return "todo"
class Flask(): def __init__(self, host): self.__name__ = __name__ self.keyChain = KeyChain() self.isDone = False self.counter = 0 loop = asyncio.get_event_loop() self.face = ThreadsafeFace(loop, host) self.a = {} self.methods = {} def route(self, uri, methods): self.baseName = ndn.Name(uri) self.methods[self.baseName] = methods[0] return self.dec def onInterest(self, prefix, interest, *k): print >> sys.stderr, "<< PyNDN %s" % interest.name print prefix d = self.a[prefix] if self.methods[prefix] == "POST": content = json.dumps( d(interest.getContent().toRawStr().decode('string_escape'))) else: content = json.dumps(d()) self.counter += 1 #print interest.getContent().toRawStr().decode('string_escape') data = ndn.Data(interest.getName()) meta = ndn.MetaInfo() meta.setFreshnessPeriod(5000) data.setMetaInfo(meta) data.setContent(content) self.keyChain.sign(data, self.keyChain.getDefaultCertificateName()) self.face.putData(data) def _onRegisterFailed(self, prefix): print >> sys.stderr, "<< PyNDN: failed to register prefix" def run(self): root = logging.getLogger() root.setLevel(logging.DEBUG) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) root.addHandler(ch) loop = asyncio.get_event_loop() #face = ThreadsafeFace(loop, "172.17.0.1") #face = ndn.Face("172.17.0.1","6363") server = Server(self.face) loop.run_forever() face.shutdown() def dec(self, func): self.a[self.baseName] = func print self.a self.face.registerPrefix( self.baseName, self.onInterest, self._onRegisterFailed, )
class BaseNode(object): """ This class contains methods/attributes common to both node and controller. """ def __init__(self, transport = None, conn = None): """ Initialize the network and security classes for the node """ super(BaseNode, self).__init__() self.faceTransport = transport self.faceConn = conn self._identityStorage = BasicIdentityStorage() self._identityManager = IdentityManager(self._identityStorage, FilePrivateKeyStorage()) self._policyManager = IotPolicyManager(self._identityStorage) # hopefully there is some private/public key pair available self._keyChain = KeyChain(self._identityManager, self._policyManager) self._registrationFailures = 0 self._prepareLogging() self._setupComplete = False ## # 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._policyManager.getDeviceIdentity()) except SecurityException as e: # zhehao: in the case of producer's /localhop prefixes, the default key is not defined in ndnsec-public-info.db certName = self._keyChain.createIdentityAndCertificate(self._policyManager.getDeviceIdentity()) #certName = self._keyChain.getDefaultCertificateName() #print(certName.toUri()) 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() if (self.faceTransport == None or self.faceTransport == ''): self.face = ThreadsafeFace(self.loop) else: self.face = ThreadsafeFace(self.loop, self.faceTransport, self.faceConn) self.face.setCommandSigningInfo(self._keyChain, self.getDefaultCertificateName()) self._keyChain.setFace(self.face) self._isStopped = False self.beforeLoopStart() try: self.loop.run_forever() except Exception as e: self.log.exception(exc_info=True) finally: self.stop() def stop(self): """ Stops the node, taking it off the network """ self.log.info("Shutting down") self._isStopped = True self.loop.stop() ### # 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, sign=True): """ Reply to an interest with a data packet, optionally signing it. :param pyndn.Data data: The response data packet :param boolean sign: (optional, default=True) Whether the response must be signed. """ if sign: self.signData(data) self.face.putData(data) ### # # ## 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.faceTransport != None and self.faceConn != None: self.log.warn("Explicit face transport and connectionInfo: Could not register {}; expect a manual or autoreg on the other side.".format(prefix.toUri())) elif 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.info("Prefix registration failed") self.stop() 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 getSerial(): """ 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 """ try: if PLATFORM == "raspberry pi": with open('/proc/cpuinfo') as f: for line in f: if line.startswith('Serial'): return line.split(':')[1].strip() else: return "todo" except NameError: return "todo"
class Flask(): def __init__(self, host): self.__name__ = __name__ self.keyChain = KeyChain() self.isDone = False self.counter = 0 loop = asyncio.get_event_loop() self.face = ThreadsafeFace(loop, host) self.a = {} self.methods = {} def route(self, uri, methods): prefix = uri if bool(re.search('<(.*)>', prefix)): self.baseName = ndn.Name( re.sub('<(.*)>', methods[0] + '/<data>', prefix)) else: self.baseName = ndn.Name(prefix + "/" + methods[0]) self.methods[self.baseName.toUri()] = methods[0] return self.dec def onInterest(self, prefix, interest, *k): print >> sys.stderr, "<< PyNDN %s" % interest.name intrestUri = interest.name.toUri() prefixUri = prefix.toUri() parameters = '' if intrestUri != prefixUri: parameters = intrestUri[len(prefixUri) + 1:] print prefixUri += "/%3Cdata%3E" d = self.a[prefixUri] if self.methods[prefixUri] == "POST": content = json.dumps( d(interest.getContent().toRawStr().decode('string_escape'))) else: if parameters: content = json.dumps(d(parameters)) else: content = json.dumps(d()) self.counter += 1 data = ndn.Data(interest.getName()) meta = ndn.MetaInfo() meta.setFreshnessPeriod(5000) data.setMetaInfo(meta) data.setContent(content) self.keyChain.sign(data, self.keyChain.getDefaultCertificateName()) self.face.putData(data) def _onRegisterFailed(self, prefix): print >> sys.stderr, "<< PyNDN: failed to register prefix" def run(self): root = logging.getLogger() root.setLevel(logging.DEBUG) ch = logging.StreamHandler(sys.stdout) ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) root.addHandler(ch) loop = asyncio.get_event_loop() server = Server(self.face) loop.run_forever() self.face.shutdown() def dec(self, func): self.a[self.baseName.toUri()] = func self.face.registerPrefix( self.baseName, self.onInterest, self._onRegisterFailed, )