Exemplo n.º 1
0
def main():

    # COMMAND LINE ARGS
    parser = argparse.ArgumentParser(
        description='Parse or follow Cascade Datahub log and publish to NDN.')
    parser.add_argument('filename', help='datahub log file')
    parser.add_argument('-f',
                        dest='follow',
                        action='store_true',
                        help='follow (tail -f) the log file')
    parser.add_argument('--namespace',
                        default='/ndn/edu/ucla/remap/bms',
                        help='root ndn name, no trailing slash')
    args = parser.parse_args()

    # NDN
    global face, keychain
    loop = asyncio.get_event_loop()
    face = ThreadsafeFace(loop, "localhost")

    keychain = KeyChain(
        IdentityManager(
            BasicIdentityStorage(),
            FilePrivateKeyStorage()))  # override default even for MacOS
    cache = MemoryContentCache(face)

    # READ THE FILE (MAIN LOOP)
    if args.follow:
        loop.run_until_complete(
            followfile(args.filename, args.namespace, cache))
    else:
        loop.run_until_complete(readfile(args.filename, args.namespace, cache))

    face.shutdown()
Exemplo n.º 2
0
class ThreadsafeFaceWrapper(object):
    def __init__(self):
        self._loop = asyncio.get_event_loop()
        self._face = ThreadsafeFace(self._loop, "")
        self._keyChain = KeyChain()
        self._certificateName = self._keyChain.getDefaultCertificateName()
        self._face.setCommandSigningInfo(self._keyChain, self._certificateName)
	
        
    def startProcessing(self):
        try:
            self._loop.run_forever()        
        finally:
            self.stop()
        
    def stopProcessing(self):
        self._loop.close()
        self._face.shutdown()
        self._face = None
        sys.exit(1)
    
    def getFace(self):
        return self._face
        
    def getLoop(self):
        return self._loop
Exemplo n.º 3
0
    def start(self):
        """
        Start up the UI
        """
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, '')

        controllerCertificateName = self._identityStorage.getDefaultCertificateNameForIdentity(
            self.prefix)
        self.face.setCommandSigningInfo(self._keyChain,
                                        controllerCertificateName)
        self._keyChain.setFace(
            self.face)  # shouldn't be necessarym but doesn't hurt

        self._isStopped = False
        self.face.stopWhen(lambda: self._isStopped)

        self.loop.call_soon(self.displayMenu)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            pass
        except Exception as e:
            print(e)
            #self.log('Exception', e)
        finally:
            self._isStopped = True
Exemplo n.º 4
0
    def start(self):
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, "")
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.songName = raw_input(
            "Song Name(each song separated by a comma): ")
        self.device = raw_input("Music Player: ")
        self.issueSongCommand()

        try:
            self.loop.run_forever()
        finally:
            self.stop()
Exemplo n.º 5
0
    def start(self):
        self._loop = asyncio.get_event_loop()
        self._face = ThreadsafeFace(self._loop, "")
        self._face.setCommandSigningInfo(self._keyChain, self._certificateName)
        self._face.registerPrefix(self.prefix, self.onPlayingCommand,
                                  self.onRegisterFailed)

        try:
            self._loop.run_forever()
        except KeyboardInterrupt:
            sys.exit()
        finally:
            self.stop()
Exemplo n.º 6
0
def main():
    loop = asyncio.get_event_loop()
    face = ThreadsafeFace(loop, "localhost")
    keyChain = KeyChain()
    face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName())

    # TODO: NFD hack: uncomment once NFD forwarding fixed
    # discoveree = Discoveree(loop, face, keyChain)
    # TODO: NFD hack: remove once NFD forwarding fixed
    discoveree = LocalDiscoveree(loop, face, keyChain)

    cecTv = CecTv(loop, face, keyChain, discoveree)

    loop.run_forever()
    face.shutdown()
Exemplo n.º 7
0
    def start(self):
        print "reg start"
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, self.address)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.face.registerPrefix(self.prefix, self.onInterest,
                                 self.onRegisterFailed)
        self._isStopped = False
        self.face.stopWhen(lambda: self._isStopped)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:

            sys.exit()
        finally:
            self.stop()
Exemplo n.º 8
0
    def start(self):
        self.isStopped = False
        self.loop = asyncio.get_event_loop()
        
        self.face = ThreadsafeFace(self.loop, '')
        self.keyFace = ThreadsafeFace(self.loop, 'borges.metwi.ucla.edu')
        self.face.stopWhen(lambda:self.isStopped)
        self.keyFace.stopWhen(lambda:self.isStopped)

        k = KeyChain()
        self.face.setCommandSigningInfo(k, k.getDefaultCertificateName())
        try:
            self.loop.run_until_complete(self.parseDataRequest())
        except (EOFError, KeyboardInterrupt):
            pass
        finally:
            self.face.shutdown()
Exemplo n.º 9
0
    def start(self):
        self.initializeDatabase()
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, '')
        self.face.setCommandSigningInfo(self.keyChain, 
                self.keyChain.getDefaultCertificateName())
        self._register(self.dataPrefix, self.handleDataInterests)
        self._register(self.repoPrefix, self.handleCommandInterests)

        #TODO: figure out why nfdc doesn't forward to borges
        self._insertFace = ThreadsafeFace(self.loop, 'borges.metwi.ucla.edu')

        try:
            self.loop.run_forever()
        except Exception as e:
            self.log.exception(e, exc_info=True)
            self.face.shutdown()
Exemplo n.º 10
0
    def start(self):
        self.loop = asyncio.new_event_loop()
        self.face = ThreadsafeFace(self.loop, "")
        self.dataCache = MemoryContentCache(self.face, 100)

        asyncio.set_event_loop(self.loop)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)

        self.dataCache.registerPrefix(self.dataPrefix, self.onRegisterFailed)
        self.loop.run_until_complete(self.insertNewVersion())
Exemplo n.º 11
0
 def start(self):
     self.isStopped = False
     self.loop = asyncio.new_event_loop()
     asyncio.set_event_loop(self.loop)
     self.face = ThreadsafeFace(self.loop, '')
     k = KeyChain()
     self.face.setCommandSigningInfo(k, k.getDefaultCertificateName())
     self.face.stopWhen(lambda:self.isStopped)
     try:
         self.loop.run_until_complete(self.sendNextInsertRequest())
     finally:
         self.face.shutdown()
    def start(self):
        self.loop = asyncio.new_event_loop()
        self.face = ThreadsafeFace(self.loop, "")

        asyncio.set_event_loop(self.loop)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.face.registerPrefix(self.dataPrefix,self.onPublishInterest, self.onRegisterFailed)
        try:
            self.loop.call_soon(self.kickRepo)
            self.loop.run_forever()
        finally:
           self.stop() 
Exemplo n.º 13
0
    def start(self):
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, "")
        self.face.setCommandSigningInfo(self.keychain, self.certificateName) 
        self.songName = raw_input("Song Name(each song separated by a comma): ")
	self.device = raw_input("Music Player: ")
        self.issueSongCommand()
        
        try:
            self.loop.run_forever()
        finally:
            self.stop()
Exemplo n.º 14
0
    def start(self):
        self._loop = asyncio.get_event_loop()
        self._face = ThreadsafeFace(self._loop,"")
        self._face.setCommandSigningInfo(self._keyChain, self._certificateName)
        self._face.registerPrefix(self.prefix, self.onPlayingCommand, self.onRegisterFailed)
	print "after register prefix"
        try:
            self._loop.run_forever()
        except KeyboardInterrupt:
            sys.exit()
        finally:
            self.stop()
Exemplo n.º 15
0
def main():
    loop = asyncio.get_event_loop()
    face = ThreadsafeFace(loop, "aleph.ndn.ucla.edu")

    counter = Counter()
    face.stopWhen(lambda: counter._callbackCount >= 1)

    name1 = Name("/")
    dump("Express name ", name1.toUri())
    # This call to exressIinterest is thread safe because face is a ThreadsafeFace.
    face.expressInterest(name1, counter.onData, counter.onTimeout)

    # Run until stopWhen stops the loop.
    loop.run_forever()
    face.shutdown()
Exemplo n.º 16
0
    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
Exemplo n.º 17
0
    def start(self):
	print "reg start"
	self.loop = asyncio.get_event_loop()
	self.face = ThreadsafeFace(self.loop,self.address)
	self.face.setCommandSigningInfo(self.keychain,self.certificateName)
        self.face.registerPrefix(self.prefix,self.onInterest,self.onRegisterFailed)
        self._isStopped = False
        self.face.stopWhen(lambda:self._isStopped)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:

            sys.exit()
        finally:
            self.stop()
Exemplo n.º 18
0
def main():
    loop = asyncio.get_event_loop()
    face = ThreadsafeFace(loop, "aleph.ndn.ucla.edu")

    counter = Counter()
    face.stopWhen(lambda: counter._callbackCount >= 1)

    name1 = Name("/") 
    dump("Express name ", name1.toUri())
    # This call to exressIinterest is thread safe because face is a ThreadsafeFace.
    face.expressInterest(name1, counter.onData, counter.onTimeout)

    # Run until stopWhen stops the loop.
    loop.run_forever()
    face.shutdown()
Exemplo n.º 19
0
def main():
    loop = asyncio.get_event_loop()
    face = ThreadsafeFace(loop, "localhost")
    keyChain = KeyChain()
    face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName())

    # TODO: NFD hack: uncomment once NFD forwarding fixed
    # discoveree = Discoveree(loop, face, keyChain)
    # TODO: NFD hack: remove once NFD forwarding fixed
    discoveree = LocalDiscoveree(loop, face, keyChain)

    cecTv = CecTv(loop, face, keyChain, discoveree)

    loop.run_forever()
    face.shutdown()
Exemplo n.º 20
0
    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
Exemplo n.º 21
0
    def start(self):
        """
        Start up the UI
        """
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, "")

        controllerCertificateName = self._identityStorage.getDefaultCertificateNameForIdentity(self.prefix)
        self.face.setCommandSigningInfo(self._keyChain, controllerCertificateName)
        self._keyChain.setFace(self.face)  # shouldn't be necessarym but doesn't hurt

        self._isStopped = False
        self.face.stopWhen(lambda: self._isStopped)

        self.loop.call_soon(self.displayMenu)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            pass
        except Exception as e:
            print(e)
            # self.log('Exception', e)
        finally:
            self._isStopped = True
Exemplo n.º 22
0
        self.songName = raw_input("Song Name(each song separated by a comma): ")
        self.device = raw_input("Music Player: ")
        self.issueSongCommand()
    
def runForever(loop):
        try:
            loop.run_forever()
        finally:
            sys.exit()        
        
if __name__ == '__main__':

        skeychain = KeyChain()
        scertificateName = skeychain.getDefaultCertificateName()
        sloop = asyncio.get_event_loop()
        sface = ThreadsafeFace(sloop, "")
        
        sface.setCommandSigningInfo(skeychain, scertificateName) 
    
        t = threading.Thread(target = runForever, args = (sloop,))
        t.daemon = True
        t.start()
    
        #obtaining song list
        lq = ListRequiry(skeychain,sloop,sface)
        lq.start()
	songList = []
	songList = lq.onListTimeout()
        #wait for 10 sec 
        time.sleep(10)
        #order song
Exemplo n.º 23
0
class IotConsole(object):
    """
    This uses the controller's credentials to provide a management interface
    to the user.
    It does not go through the security handshake (as it should be run on the
    same device as the controller) and so does not inherit from the BaseNode.
    """

    def __init__(self, networkName, nodeName):
        super(IotConsole, self).__init__()

        self.deviceSuffix = Name(nodeName)
        self.networkPrefix = Name(networkName)
        self.prefix = Name(self.networkPrefix).append(self.deviceSuffix)

        self._identityStorage = IotIdentityStorage()
        self._policyManager = IotPolicyManager(self._identityStorage)
        self._identityManager = IotIdentityManager(self._identityStorage)
        self._keyChain = KeyChain(self._identityManager, self._policyManager)

        self._policyManager.setEnvironmentPrefix(self.networkPrefix)
        self._policyManager.setTrustRootIdentity(self.prefix)
        self._policyManager.setDeviceIdentity(self.prefix)
        self._policyManager.updateTrustRules()

        self.foundCommands = {}
        self.unconfiguredDevices = []

        # TODO: use xDialog in XWindows
        self.ui = Dialog(backtitle="NDN IoT User Console", height=18, width=78)

        trolliusLogger = logging.getLogger("trollius")
        trolliusLogger.addHandler(logging.StreamHandler())

    def start(self):
        """
        Start up the UI
        """
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, "")

        controllerCertificateName = self._identityStorage.getDefaultCertificateNameForIdentity(self.prefix)
        self.face.setCommandSigningInfo(self._keyChain, controllerCertificateName)
        self._keyChain.setFace(self.face)  # shouldn't be necessarym but doesn't hurt

        self._isStopped = False
        self.face.stopWhen(lambda: self._isStopped)

        self.loop.call_soon(self.displayMenu)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            pass
        except Exception as e:
            print(e)
            # self.log('Exception', e)
        finally:
            self._isStopped = True

    def stop(self):
        self._isStopped = True

    #######
    # GUI
    #######

    def displayMenu(self):

        menuOptions = OrderedDict(
            [
                ("List network services", self.listCommands),
                ("Pair a device", self.pairDevice),
                ("Express interest", self.expressInterest),
                ("Quit", self.stop),
            ]
        )
        (retCode, retStr) = self.ui.mainMenu("Main Menu", menuOptions.keys())

        if retCode == Dialog.DIALOG_ESC or retCode == Dialog.DIALOG_CANCEL:
            # TODO: ask if you're sure you want to quit
            self.stop()
        if retCode == Dialog.DIALOG_OK:
            menuOptions[retStr]()

    #######
    # List all commands
    ######
    def listCommands(self):
        self._requestDeviceList(self._showCommandList, self.displayMenu)

    def _requestDeviceList(self, successCallback, timeoutCallback):
        self.ui.alert("Requesting services list...", False)
        interestName = Name(self.prefix).append("listCommands")
        interest = Interest(interestName)
        interest.setInterestLifetimeMilliseconds(3000)
        # self.face.makeCommandInterest(interest)
        self.face.expressInterest(
            interest,
            self._makeOnCommandListCallback(successCallback),
            self._makeOnCommandListTimeoutCallback(timeoutCallback),
        )

    def _makeOnCommandListTimeoutCallback(self, callback):
        def onCommandListTimeout(interest):
            self.ui.alert("Timed out waiting for services list")
            self.loop.call_soon(callback)

        return onCommandListTimeout

    def _makeOnCommandListCallback(self, callback):
        def onCommandListReceived(interest, data):
            try:
                commandInfo = json.loads(str(data.getContent()))
            except:
                self.ui.alert("An error occured while reading the services list")
                self.loop.call_soon(self.displayMenu)
            else:
                self.foundCommands = commandInfo
                self.loop.call_soon(callback)

        return onCommandListReceived

    def _showCommandList(self):
        try:
            commandList = []
            for capability, commands in self.foundCommands.items():
                commandList.append("\Z1{}:".format(capability))
                for info in commands:
                    signingStr = "signed" if info["signed"] else "unsigned"
                    commandList.append("\Z0\t{} ({})".format(info["name"], signingStr))
                commandList.append("")

            if len(commandList) == 0:
                # should not happen
                commandList = ["----NONE----"]
            allCommands = "\n".join(commandList)
            oldTitle = self.ui.title
            self.ui.title = "Available services"
            self.ui.alert(allCommands, preExtra=["--colors"])
            self.ui.title = oldTitle
            # self.ui.menu('Available services', commandList, prefix='', extras=['--no-cancel'])
        finally:
            self.loop.call_soon(self.displayMenu)

    #######
    # New device
    ######

    def pairDevice(self):
        self._scanForUnconfiguredDevices()

    def _enterPairingInfo(self, serial, pin="", newName=""):
        fields = [Dialog.FormField("PIN", pin), Dialog.FormField("Device name", newName)]
        (retCode, retList) = self.ui.form("Pairing device {}".format(serial), fields)
        if retCode == Dialog.DIALOG_OK:
            pin, newName = retList
            if len(pin) == 0 or len(newName) == 0:
                self.ui.alert("All fields are required")
                self.loop.call_soon(self._enterPairingInfo, serial, pin, newName)
            else:
                try:
                    pinBytes = pin.decode("hex")
                except TypeError:
                    self.ui.alert("Pin is invalid")
                    self.loop.call_soon(self._enterPairingInfo, serial, pin, newName)
                else:
                    self._addDeviceToNetwork(serial, newName, pin.decode("hex"))
        elif retCode == Dialog.DIALOG_CANCEL or retCode == Dialog.DIALOG_ESC:
            self.loop.call_soon(self._showConfigurationList)

    def _showConfigurationList(self):
        foundDevices = self.unconfiguredDevices[:]
        emptyStr = "----NONE----"
        if len(foundDevices) == 0:
            foundDevices.append(emptyStr)
        retCode, retStr = self.ui.menu(
            "Select a device to configure",
            foundDevices,
            preExtras=["--ok-label", "Configure", "--extra-button", "--extra-label", "Refresh"],
        )
        if retCode == Dialog.DIALOG_CANCEL or retCode == Dialog.DIALOG_ESC:
            self.loop.call_soon(self.displayMenu)
        elif retCode == Dialog.DIALOG_EXTRA:
            self.loop.call_soon(self._scanForUnconfiguredDevices)
        elif retCode == Dialog.DIALOG_OK and retStr != emptyStr:
            self.loop.call_soon(self._enterPairingInfo, retStr)
        else:
            self.loop.call_soon(self._showConfigurationList)

    def _scanForUnconfiguredDevices(self):
        # unconfigured devices should register '/localhop/configure'
        # we keep asking for unconfigured devices until we stop getting replies

        foundDevices = []

        self.ui.alert("Scanning for unconfigured devices...", False)

        def onDeviceTimeout(interest):
            # assume we're done - everyone is excluded
            self.unconfiguredDevices = foundDevices
            self.loop.call_soon(self._showConfigurationList)

        def onDeviceResponse(interest, data):
            updatedInterest = Interest(interest)
            deviceSerial = str(data.getContent())
            if len(deviceSerial) > 0:
                foundDevices.append(deviceSerial)
                updatedInterest.getExclude().appendComponent(Name.Component(deviceSerial))
            # else ignore the malformed response
            self.face.expressInterest(updatedInterest, onDeviceResponse, onDeviceTimeout)

        interest = Interest(Name("/localhop/configure"))
        interest.setInterestLifetimeMilliseconds(2000)
        self.face.expressInterest(interest, onDeviceResponse, onDeviceTimeout)

    def _addDeviceToNetwork(self, serial, suffix, pin):
        self.ui.alert("Sending pairing info to gateway...", False)
        # we must encrypt this so no one can see the pin!
        message = DevicePairingInfoMessage()
        message.info.deviceSuffix = suffix
        message.info.deviceSerial = serial
        message.info.devicePin = pin
        rawBytes = ProtobufTlv.encode(message)
        encryptedBytes = self._identityManager.encryptForIdentity(rawBytes, self.prefix)
        encodedBytes = base64.urlsafe_b64encode(str(encryptedBytes))
        interestName = Name(self.prefix).append("addDevice").append(encodedBytes)
        interest = Interest(interestName)
        # todo: have the controller register this console as a listener
        # and update it with pairing status
        interest.setInterestLifetimeMilliseconds(5000)
        self.face.makeCommandInterest(interest)

        self.face.expressInterest(interest, self._onAddDeviceResponse, self._onAddDeviceTimeout)

    def _onAddDeviceResponse(self, interest, data):
        try:
            responseCode = int(str(data.getContent()))
            if responseCode == 202:
                self.ui.alert("Gateway received pairing info")
            else:
                self.ui.alert("Error encountered while sending pairing info")
        except:
            self.ui.alert("Exception encountered while decoding gateway reply")
        finally:
            self.loop.call_soon(self.displayMenu)

    def _onAddDeviceTimeout(self, interest):
        self.ui.alert("Timed out sending pairing info to gateway")
        self.loop.call_soon(self.displayMenu)

    ######
    # Express interest
    #####

    def expressInterest(self):
        if len(self.foundCommands) == 0:
            self._requestDeviceList(self._showInterestMenu, self._showInterestMenu)
        else:
            self.loop.call_soon(self._showInterestMenu)

    def _showInterestMenu(self):
        # display a menu of all available interests, on selection allow user to
        # (1) extend it
        # (2) send it signed/unsigned
        # NOTE: should it add custom ones to the list?
        commandSet = set()
        wildcard = "<Enter Interest Name>"
        try:
            for commands in self.foundCommands.values():
                commandSet.update([c["name"] for c in commands])
            commandList = list(commandSet)
            commandList.append(wildcard)
            (returnCode, returnStr) = self.ui.menu("Choose a command", commandList, prefix=" ")
            if returnCode == Dialog.DIALOG_OK:
                if returnStr == wildcard:
                    returnStr = self.networkPrefix.toUri()
                self.loop.call_soon(self._expressCustomInterest, returnStr)
            else:
                self.loop.call_soon(self.displayMenu)
        except:
            self.loop.call_soon(self.displayMenu)

    def _expressCustomInterest(self, interestName):
        # TODO: make this a form, add timeout field
        try:
            handled = False
            (returnCode, returnStr) = self.ui.prompt(
                "Send interest",
                interestName,
                preExtra=["--extra-button", "--extra-label", "Signed", "--ok-label", "Unsigned"],
            )
            if returnCode == Dialog.DIALOG_ESC or returnCode == Dialog.DIALOG_CANCEL:
                self.loop.call_soon(self.expressInterest)
            else:
                interestName = Name(returnStr)
                doSigned = returnCode == Dialog.DIALOG_EXTRA
                interest = Interest(interestName)
                interest.setInterestLifetimeMilliseconds(5000)
                interest.setChildSelector(1)
                interest.setMustBeFresh(True)
                if doSigned:
                    self.face.makeCommandInterest(interest)
                self.ui.alert("Waiting for response to {}".format(interestName.toUri()), False)
                self.face.expressInterest(interest, self.onDataReceived, self.onInterestTimeout)
        except:
            self.loop.call_soon(self.expressInterest)

    def onInterestTimeout(self, interest):
        try:
            self.ui.alert("Interest timed out:\n{}".format(interest.getName().toUri()))
        except:
            self.ui.alert("Interest timed out")
        finally:
            self.loop.call_soon(self.expressInterest)

    def onDataReceived(self, interest, data):
        try:
            dataString = "{}\n\n".format(data.getName().toUri())
            dataString += "Contents:\n{}".format(repr(data.getContent().toRawStr()))
            self.ui.alert(dataString)
        except:
            self.ui.alert("Exception occured displaying data contents")
        finally:
            self.loop.call_soon(self.expressInterest)
Exemplo n.º 24
0
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 = IotIdentityStorage()
        self._identityManager = IotIdentityManager(self._identityStorage)
        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
        self._instanceSerial = None

        # waiting devices register this prefix and respond to discovery
        # or configuration interest
        self._hubPrefix = Name('/localhop/configure')

    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._policyManager.getDeviceIdentity())
        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()
Exemplo n.º 25
0
class NdnRepoClient(object):
    def __init__(self, repoPrefix=None):
        super(NdnRepoClient, self).__init__()
        if repoPrefix is not None:
            self.repoPrefix = Name(repoPrefix)
        else:
            self.repoPrefix = Name('/test/repo')
        self.loadKey()
        self.isStopped = False
        self.dataReady = asyncio.Event()
        self.resultQueue = asyncio.Queue()

        self.log = logging.getLogger(str(self.__class__))
        h = logging.FileHandler('repo_client.log')
        s = logging.StreamHandler()
        logFormatter = logging.Formatter(
            '%(asctime)-15s %(levelname)-8s %(funcName)s\n\t%(message)s')
        s.setFormatter(logFormatter)
        h.setFormatter(logFormatter)
        self.log.addHandler(h)
        self.log.addHandler(s)
        s.setLevel(logging.WARN)
        self.log.setLevel(logging.DEBUG)
        self.isStopped = True
        logging.getLogger('trollius').addHandler(h)

        self.knownKeys = {}
        self.pendingKeys = []

    def loadKey(self, keyFile='bms_key.pri'):
        self.keyId = '\xa2\xeb9\xbcGo$\xad\xbf\xe9?k\xb2\xb8|\xa8 E\x96\x13\x1e\xb9\x97\x91Z\xf6\xda\xd1]\xa1lD'
        with open(keyFile, 'r') as keyFile:
            binDer = keyFile.read()
            self.privateKey = RSA.importKey(binDer)

    @asyncio.coroutine
    def _decryptAndPrintRecord(self, recordData, keyName, parentDoc):
        keyUri = keyName.toUri()
        def cleanString(dirty):
            return ''.join(filter(string.printable.__contains__, str(dirty)))

        def onKeyDataReceived(keyInterest, keyData):
            self.log.debug('Got key for {}'.format(keyInterest.getName()))
            cipherText = str(keyData.getContent())
            symKeyRaw = self.privateKey.decrypt(cipherText)
            symKey = symKeyRaw[-64:].decode('hex')

            msg = recordData[8:]
            iv = msg[:16]
            cipherText = msg[16:]

            cipher = AES.new(key=symKey, IV=iv, mode=AES.MODE_CBC)
            decData = cleanString(cipher.decrypt(cipherText))

            fromJson = json.loads(decData)
            fromJson.update(parentDoc)
            self.knownKeys[keyUri] = keyData
            try:
                self.pendingKeys.remove(keyUri)
            except ValueError:
                pass # already removed

            self.resultQueue.put_nowait(fromJson)

        def onKeyTimeout(keyInterest):
            self.log.error('Could not get decryption key for {}'.format(keyInterest.getName()))
            self.resultQueue.put_nowait({})

        i = Interest(keyName)
        i.setMustBeFresh(False)
        i.setInterestLifetimeMilliseconds(2000)

        if keyUri in self.knownKeys:
            self.log.debug('Using known key')
            onKeyDataReceived(i, self.knownKeys[keyUri])
        elif keyUri in self.pendingKeys:
            self.log.debug('Waiting on pending key')
            timeout = 0
            while keyUri not in self.knownKeys:
                yield From(asyncio.sleep(0.5))
                timeout += 1
                if timeout > 5:
                    self.log.warn('Timed out on key {}'.format(keyUri))
                    onKeyTimeout(i)
                    break
            else:
                onKeyDataReceived(i, self.knownKeys[keyUri])
        else:
            self.log.debug('Adding {} to pending keys'.format(keyUri))
            self.pendingKeys.append(keyUri)
            self.keyFace.expressInterest(i, onKeyDataReceived, onKeyTimeout)

    def prettifyResults(self, resultsList):
        # dictionary comparison is by length (# of k:v pairs)
        allKeys = max(resultsList).keys()
        columnWidths = {}
        for k in allKeys:
            if k == 'ts':
                columnWidths[k] = len(max([(result[k]).isoformat() for result in resultsList 
                    if k in result]))
            else:
                columnWidths[k] = len(max([str(result[k]) for result in resultsList 
                    if k in result]))
            columnWidths[k] = max(columnWidths[k], len(k)+2)
        headerLen = sum(columnWidths.values())+len(k)
        print '-'*headerLen
        headers = []
        for k in allKeys:
            headers.append('{0:^{1}}'.format(k, columnWidths[k]))
        print '|'+'|'.join(headers)+'|'
        print '-'*headerLen
        for result in resultsList:
            line = []
            for k in allKeys:
                if k not in result:
                    val = ''
                elif k == 'ts':
                    val = result[k].isoformat()
                else:
                    val = result[k]
                line.append('{0:^{1}}'.format(val, columnWidths[k]))
            print '|'+'|'.join(line)+'|'
        print '-'*headerLen

    @asyncio.coroutine
    def collectResults(self, allData):
        try:
            for record in allData:
                parentDoc = {k:v for (k,v) in record.items() if k not in [u'_id', u'value']} 
                aDataVal = str(record[u'value'])
                keyTs = aDataVal[:8]
                keyDataName = Name('/ndn/ucla.edu/bms/melnitz/kds').append(keyTs).append(self.keyId)
                yield From(self._decryptAndPrintRecord(aDataVal, keyDataName, parentDoc))
            receivedVals = []
            try:
                for i in asyncio.as_completed([
                    self.resultQueue.get() for n in range(len(allData))], timeout=5):
                    v = yield From(i)
                    receivedVals.append(v)
            except asyncio.TimeoutError:
                pass
            self.prettifyResults(receivedVals)
            print
        finally:
            self.dataReady.set()

    def onDataReceived(self, interest, data):
        # now we have to retrieve the key
        dataContent = str(data.getContent())
        dataContent = BSON(dataContent)
        dataDict = dataContent.decode()

        allData = dataDict['results']
        totalCount = dataDict['count']
        dataCount = len(allData)
        skipPos = dataDict['skip']
        print '---------'
        print 'Got {}/{} result(s), starting at {}'.format(dataCount, totalCount, skipPos)

        asyncio.async(self.collectResults(allData))

    def onDataTimeout(self, interest):
        self.log.warn("Timed out on {}".format(interest.toUri()))
        self.dataReady.set()

    def sendDataRequestCommand(self, dataName):
        interest = Interest(dataName)
        interest.setInterestLifetimeMilliseconds(4000)
        self.face.expressInterest(interest, self.onDataReceived, self.onDataTimeout)
        return interest

    def stop(self):
        self.isStopped = True

    def parseSqlSelect(self, statement):
        statement = statement.strip()
        queryDict = {}
        try:
            selection, parts = re.split(r'\s+WHERE\s+', statement, flags=re.I) 
        except ValueError:
            print 'WHERE clause is missing'
            return  None
        
        selectMatch = re.match(r'^SELECT\s+(?:(\*)|(\w+,(\s*\w+)*))', selection, flags=re.I)
        if selectMatch is None:
            print 'Malformed SELECT'
            return None

        expressions = re.split(r'\s+AND\s+', parts, flags=re.I)
        for ex in expressions:
            if len(ex) == 0:
                continue
            try:
                k,v = ex.split('=')
            except ValueError:
                print 'Malformed WHERE clause {}'.format(ex)
            else:
                queryDict[k.strip()] = v.strip()
        return queryDict

        # get = pairs
    def assembleDataName(self):
        schemaStr = ('/ndn/ucla.edu/bms/{building}/data/{room}/electrical/panel/{panel_name}/{quantity}/{data_type}')
        keyNames = ['building', 'room', 'panel_name', 'quantity', 'data_type']
        sqlStatement = raw_input('Query> ').strip()
        valueDict = self.parseSqlSelect(sqlStatement)
        if valueDict is None:
            return None
        for k in keyNames:
            valueDict.setdefault(k, '_')
        dataName = schemaStr.format(**valueDict)
        return Name(dataName)

    @asyncio.coroutine
    def parseDataRequest(self):
        while True:
            self.dataReady.clear()
            dataName = self.assembleDataName()
            if dataName is not None:
                self.loop.call_soon(self.sendDataRequestCommand, dataName)
                yield From(self.dataReady.wait())

    def start(self):
        self.isStopped = False
        self.loop = asyncio.get_event_loop()
        
        self.face = ThreadsafeFace(self.loop, '')
        self.keyFace = ThreadsafeFace(self.loop, 'borges.metwi.ucla.edu')
        self.face.stopWhen(lambda:self.isStopped)
        self.keyFace.stopWhen(lambda:self.isStopped)

        k = KeyChain()
        self.face.setCommandSigningInfo(k, k.getDefaultCertificateName())
        try:
            self.loop.run_until_complete(self.parseDataRequest())
        except (EOFError, KeyboardInterrupt):
            pass
        finally:
            self.face.shutdown()
Exemplo n.º 26
0
class SongHandler:

    def __init__(self):
        logging.basicConfig()
        self.keychain = KeyChain()
	self.certificateName = self.keychain.getDefaultCertificateName()
	self.listPrefix = "/ndn/edu/ucla/remap/music/play"
        self.face = None
        self.loop = None
	
	self.songName = ""
	self.device = ""

	self.inDecision = True


    def issueSongCommand(self):
        command = self.createSongCommand(self.songName)
        self.face.expressInterest(command,self.onSongResponse,self.onSongTimeout)
     

    def createSongCommand(self,command):
        interestName = Name(self.listPrefix).append(self.device)
	interestName = interestName.append(command)
        interest = Interest(interestName)
        return interest

    def issueStopCommand(self):
        stopInterest = self.createSongCommand("stop")
	self.face.expressInterest(stopInterest,self.onSongResponse,self.onSongTimeout)
        
    
    def issuePlayCommand(self):
        playInterest = self.createSongCommand("play")
	self.face.expressInterest(playInterest,self.onSongResponse,self.onSongTimeout)
          
  
    
    def onSongTimeout(self, interest):
	print "weird"

    def onSongResponse(self, interest, data):
	print("Whiling listening the music, you can do something else:")
        print("1.To pause, please type in '1'")
        print("2.To resume, please type in '2'")
	print("3.To change to another song, please type in the song name")
	
        cmd = raw_input(">>")
        if cmd == '1':
            self.issueStopCommand()
        if cmd == '2':
            self.issuePlayCommand()
	else:
            while True:
	    	decision = raw_input("Do you want to change your music player? Y/N : ")
	    	if decision == 'Y' or decision == 'y':
			self.device = raw_input("Music Player: ")
			break
	    	if decision =='N'or decision == 'n':
			break
	    	else:
			print "Please make sure you are typing in Y or N"				
			
	    
	    self.songName = cmd	
	    self.issueSongCommand()
         
            
            
          
    def stop(self):
        self.loop.close()
        self.face.shutdown()

    def start(self):
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, "")
        self.face.setCommandSigningInfo(self.keychain, self.certificateName) 
        self.songName = raw_input("Song Name(each song separated by a comma): ")
	self.device = raw_input("Music Player: ")
        self.issueSongCommand()
        
        try:
            self.loop.run_forever()
        finally:
            self.stop()
Exemplo n.º 27
0
class NdnHierarchicalRepo(object):
    def __init__(self, repoPrefix=None):
        super(NdnHierarchicalRepo, self).__init__()
        self.schemaList = []
        if repoPrefix is None:
            self.repoPrefix = Name('/test/repo')
        else:
            self.repoPrefix = Name(repoPrefix)
        self.keyChain = KeyChain()
        self.currentProcessId = 0

        self.pendingProcesses = {}
        self.log = logging.getLogger(str(self.__class__))
        s = logging.StreamHandler()
        formatter = logging.Formatter(
                '%(asctime)-15s %(funcName)s\n\t %(message)s')
        s.setFormatter(formatter)
        s.setLevel(logging.INFO)
        self.log.addHandler(s)
        self.log.setLevel(logging.INFO)

    def addSchema(self, schema):
        if not isinstance(schema, NdnSchema):
            schema = NdnSchema(schema)
            schema.addField('value', NdnSchema.SCHEMA_BINARY)
            schema.addField('ts', NdnSchema.SCHEMA_TIMESTAMP)
        schema.log = self.log
        self.schemaList.append(schema)
        self.dataPrefix = schema.dbPrefix

    def initializeDatabase(self):
        self.dbClient = mongo.MongoClient()
        # TODO: different DB name for different schemata?
        self.db = self.dbClient['bms']

    def _registerFailed(self, prefix):
        self.log.info('Registration failure')
        if prefix == self.dataPrefix:
            callback = self.handleDataInterests
        elif prefix == self.repoPrefix:
            callback = self.handleCommandInterests

        self.loop.call_later(5, self._register, prefix, callback)

    def _register(self, prefix, callback):
        self.face.registerPrefix(prefix, callback, self._registerFailed) 
        
    def insertData(self, data):
        dataName = data.getName()
        self.log.info('Inserting {}'.format(dataName))
        useSchema = (s for s in self.schemaList 
                if s.dbPrefix.match(dataName)).next()
        
        #exclude timestamp...
        dataFields = useSchema.matchNameToSchema(dataName[:-1])
        if len(dataFields) == 0:
            self.log.error('Invalid data name for schema')
   
        dataValue = Binary(str(data.getContent()))
        tsComponent = str(dataName[-1].getValue())
        tsConverted = float(struct.unpack("!Q", tsComponent)[0])/1000
        dataFields.update({'value':dataValue, 'ts':tsConverted})
        dataFields = useSchema.sanitizeData(dataFields)
        dataCollection = self.db['data']
        new_id = dataCollection.update(dataFields, dataFields, upsert=True)
        self.log.debug('Inserted object {}'.format(new_id))

    def start(self):
        self.initializeDatabase()
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, '')
        self.face.setCommandSigningInfo(self.keyChain, 
                self.keyChain.getDefaultCertificateName())
        self._register(self.dataPrefix, self.handleDataInterests)
        self._register(self.repoPrefix, self.handleCommandInterests)

        #TODO: figure out why nfdc doesn't forward to borges
        self._insertFace = ThreadsafeFace(self.loop, 'borges.metwi.ucla.edu')

        try:
            self.loop.run_forever()
        except Exception as e:
            self.log.exception(e, exc_info=True)
            self.face.shutdown()

    def _segmentResponseData(self, dataQuery, segmentNum=0):
        limit = 10
        startPos = segmentNum*limit
        results = self.db['data'].find(dataQuery).skip(segmentNum*limit).limit(limit)
        return(startPos, results)


    def handleDataInterests(self, prefix, interest, transport, prefixId):
        # TODO: verification
        
        # we match the components to the name, and any '_' components
        # are discarded. Then we run a MongoDB query and append the
        # object id to allow for excludes

        chosenSchema = (s for s in self.schemaList 
                if s.dbPrefix.match(prefix)).next()

        interestName = interest.getName()
        responseName = Name(interestName)
        nameFields = chosenSchema.matchNameToSchema(interestName)
        self.log.info("Data requested with params:\n\t{}".format(nameFields))
        allResults = []
        segment = 0
        try:
            segmentComponent = interest.getName()[-4]
            segment = segmentComponent.toSegment()
        except RuntimeError:
            pass
        
        (startPos, results) = self._segmentResponseData(nameFields, segment)
        for result in results:
            dataId = result[u'_id']
            self.log.debug("Found object {}".format(dataId))
            allResults.append(result)

        #responseName.append(str(dataId))
        totalCount = results.count(False)
        responseObject = {'count':totalCount, 'skip':startPos, 'results':allResults}
        responseData = Data(responseName)
        resultEncoded = BSON.encode(responseObject)
        responseData.setContent(resultEncoded)
        transport.send(responseData.wireEncode().buf())


    def _onInsertionDataReceived(self, interest, data):
        # TODO: update status in processingList
        self.log.debug("Got {} in response to {}".format(data.getName(), 
                interest.getName()))
        self.insertData(data)
        

    def _onInsertionDataTimeout(self, interest):
        self.log.warn("Timeout on {}".format(interest.getName()))

    def handleCommandInterests(self, prefix, interest, transport, prefixId):
        # TODO: verification
        interestName = interest.getName()
        if len(interestName) <= len(prefix)+4:
            self.log.info("Bad command interest")
        commandName = str(interestName[len(prefix)].getValue())
        responseMessage =  RepoCommandResponseMessage()
        if commandName == 'insert':
            commandParams = interestName[len(prefix)+1].getValue()
            commandMessage = RepoCommandParameterMessage()
            ProtobufTlv.decode(commandMessage, commandParams)
            dataName = Name()
            fullSchemaName = Name()
            for component in commandMessage.command.name.components:
                fullSchemaName.append(component)
                if component == '_':
                    continue
                dataName.append(component)
            self.log.info("Insert request for {}".format(dataName))
            responseMessage.response.status_code = 100
            processId = self.currentProcessId
            self.currentProcessId += 1
            responseMessage.response.process_id = processId
        else:
            responseMessage.response.status_code = 403
        responseData = Data(interestName)
        responseData.setContent(ProtobufTlv.encode(responseMessage))
        transport.send(responseData.wireEncode().buf())

        # now send the interest out to the publisher
        # TODO: pendingProcesses becomes list of all processes as objects
        i = Interest(dataName)
        i.setChildSelector(1)
        i.setInterestLifetimeMilliseconds(4000)
        try:
            self.pendingProcesses[processId] = (dataName, 100)
        except NameError:
            pass # wasn't valid insert request
        else:
            self._insertFace.expressInterest(i, 
                    self._onInsertionDataReceived,
                    self._onInsertionDataTimeout)
Exemplo n.º 28
0
class SongHandler:
    def __init__(self):
        logging.basicConfig()
        self.keychain = KeyChain()
        self.certificateName = self.keychain.getDefaultCertificateName()
        self.listPrefix = "/ndn/edu/ucla/remap/music/play"
        self.face = None
        self.loop = None

        self.songName = ""
        self.device = ""

        self.inDecision = True

    def issueSongCommand(self):
        command = self.createSongCommand(self.songName)
        self.face.expressInterest(command, self.onSongResponse,
                                  self.onSongTimeout)

    def createSongCommand(self, command):
        interestName = Name(self.listPrefix).append(self.device)
        interestName = interestName.append(command)
        interest = Interest(interestName)
        return interest

    def issueStopCommand(self):
        stopInterest = self.createSongCommand("stop")
        self.face.expressInterest(stopInterest, self.onSongResponse,
                                  self.onSongTimeout)

    def issuePlayCommand(self):
        playInterest = self.createSongCommand("play")
        self.face.expressInterest(playInterest, self.onSongResponse,
                                  self.onSongTimeout)

    def onSongTimeout(self, interest):
        print "weird"

    def onSongResponse(self, interest, data):
        print("Whiling listening the music, you can do something else:")
        print("1.To pause, please type in '1'")
        print("2.To resume, please type in '2'")
        print("3.To change to another song, please type in the song name")

        cmd = raw_input(">>")
        if cmd == '1':
            self.issueStopCommand()
        if cmd == '2':
            self.issuePlayCommand()
        else:
            while True:
                decision = raw_input(
                    "Do you want to change your music player? Y/N : ")
                if decision == 'Y' or decision == 'y':
                    self.device = raw_input("Music Player: ")
                    break
                if decision == 'N' or decision == 'n':
                    break
                else:
                    print "Please make sure you are typing in Y or N"

            self.songName = cmd
            self.issueSongCommand()

    def stop(self):
        self.loop.close()
        self.face.shutdown()

    def start(self):
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, "")
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.songName = raw_input(
            "Song Name(each song separated by a comma): ")
        self.device = raw_input("Music Player: ")
        self.issueSongCommand()

        try:
            self.loop.run_forever()
        finally:
            self.stop()
class RepoPublisher:
    def __init__(self, repoPrefix, dataPrefix, dataSuffix, keychain=None):
        self.currentInsertion = -1
        self.currentStatus = -1
        self.face = None
        self.loop = None
        self.repoPrefix = Name(repoPrefix)
        self.dataName = Name(dataPrefix).append(dataSuffix)
        self.dataPrefix = Name(dataPrefix)

        if keychain is not None:
            self.keychain = keychain
        else:
            self.keychain = KeyChain()

        self.certificateName = self.keychain.getDefaultCertificateName()

        self.failureCount = 0
        self.successCount = 0

        self.processIdToVersion = {}

    def onRegisterFailed(self):
        logger.error("Could not register data publishing face!")
        self.stop()

    def versionFromCommandMessage(self, component):
        command = RepoCommandParameterMessage()
        try:
            ProtobufTlv.decode(command, component.getValue())
        except Exception as e:
            logger.warn(e)

        # last component of name to insert is version
        versionStr = command.repo_command_parameter.name.component[-1]

        return versionStr

    def stop(self):
        self.loop.close()
        self.face.shutdown()

    def onPublishInterest(self, prefix, interest, transport, pxID):
        '''
           For publishing face
        '''
        # just make up some data and return it
        interestName = interest.getName()
        logger.info("Interest for " + interestName.toUri())

        ## CURRENTLY ASSUMES THERE'S A VERSION+SEGMENT SUFFIX!
        dataName = Name(interestName)
        ts = (time.time())
        segmentId = 0
        #try:
        #   segmentId = interestName.get(-1).toSegment()
        #except:
            #logger.debug("Could not find segment id!")
            #dataName.appendSegment(segmentId)
        versionStr = str(interestName.get(-2).getValue())
        logger.debug('Publishing ' + versionStr + ' @ ' + str(ts))

        d = Data(dataName)
        content = "(" + str(ts) +  ") Data named " + dataName.toUri()
        d.setContent(content)
        d.getMetaInfo().setFinalBlockID(segmentId)
        d.getMetaInfo().setFreshnessPeriod(1000)
        self.keychain.sign(d, self.certificateName)

        encodedData = d.wireEncode()

        stats.insertDataForVersion(versionStr, {'publish_time': time.time()})
        transport.send(encodedData.toBuffer())
        #yield from asyncio.sleep()

    def generateVersionedName(self):
        fullName = Name(self.dataName)
        # currently we need to provide the version ourselves when we
        # poke the repo
        ts = int(time.time()*1000)
        fullName.appendVersion(int(ts))
        return fullName

    def onTimeout(self, prefix):
        logger.warn('Timeout waiting for '+prefix.toUri())

    
    def start(self):
        self.loop = asyncio.new_event_loop()
        self.face = ThreadsafeFace(self.loop, "")

        asyncio.set_event_loop(self.loop)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.face.registerPrefix(self.dataPrefix,self.onPublishInterest, self.onRegisterFailed)
        try:
            self.loop.call_soon(self.kickRepo)
            self.loop.run_forever()
        finally:
           self.stop() 


    def kickRepo(self):
        # command the repo to insert a new bit of data
        fullName = self.generateVersionedName()
        versionStr = str(fullName.get(-1).getValue())
        command = self.createInsertInterest(fullName)

        logger.debug('inserting: ' + versionStr)

        self.face.makeCommandInterest(command)
        def timeoutLoop(interest):
            logger.warn('Timed out on ' + interest.toUri())
            self.face.expressInterest(command, self.onCommandData, self.onTimeout)

        self.face.expressInterest(command, self.onCommandData, timeoutLoop)
        stats.insertDataForVersion(versionStr, {'insert_request':time.time()})

    def checkInsertion(self, versionStr, processID):
        fullName = Name(self.dataName).append(Name.fromEscapedString(versionStr))
        checkCommand = self.createCheckInterest(fullName, processID)
        self.face.makeCommandInterest(checkCommand)
        def timeoutLoop(interest):
            logger.warn('Timed out waiting on: '+interest.toUri())
            self.face.expressInterest(checkCommand, self.onCommandData, self.onTimeout)
        self.face.expressInterest(checkCommand, self.onCommandData, timeoutLoop)

    def createInsertInterest(self, fullName):
        '''
            For poking the repo
        '''
        # we have to do the versioning before we poke the repo
        interestName = Name(fullName)
        logger.debug('Creating insert interest for: '+interestName.toUri())
        
        insertionName = Name(self.repoPrefix).append('insert')
        commandParams = RepoCommandParameterMessage()

        for i in range(interestName.size()):
            commandParams.repo_command_parameter.name.component.append(interestName.get(i).getValue().toRawStr())

        commandParams.repo_command_parameter.start_block_id = 0
        commandParams.repo_command_parameter.end_block_id = 0

        commandName = insertionName.append(ProtobufTlv.encode(commandParams))
        interest = Interest(commandName)

        interest.setInterestLifetimeMilliseconds(2000)

        return interest

    def createCheckInterest(self, fullName, checkNum):
        insertionName = Name(self.repoPrefix).append('insert check')
        commandParams = RepoCommandParameterMessage()
        interestName = Name(fullName)

        commandParams.repo_command_parameter.process_id = checkNum
        for i in range(interestName.size()):
            commandParams.repo_command_parameter.name.component.append(str(interestName.get(i).getValue()))

        commandName = insertionName.append(ProtobufTlv.encode(commandParams))
        interest = Interest(commandName)

        return interest

    def onCommandData(self, interest, data):
        # assume it's a command response
        now = time.time()
        response = RepoCommandResponseMessage()
        ProtobufTlv.decode(response, data.getContent())


        self.currentStatus = response.repo_command_response.status_code
        self.currentInsertion =  response.repo_command_response.process_id
        logger.debug("Response status code: " + str(self.currentStatus) + ", process id: " + str(self.currentInsertion) + ", insert #" + str(response.repo_command_response.insert_num))

        command_idx = self.repoPrefix.size()
        # we also need to keep track of the mapping from version to processID for stats
        commandName = interest.getName().get(command_idx).getValue().toRawStr()
        if commandName == 'insert check':
            try:
                versionStr = self.processIdToVersion[self.currentInsertion]
                if self.currentStatus == 200:
                    stats.insertDataForVersion(versionStr, {'insert_complete': now})
                    self.loop.call_soon(self.kickRepo)
                elif self.currentStatus >= 400:
                    self.failureCount += 1
                    self.loop.call_soon(self.kickRepo)
                else:
                    self.loop.call_soon(self.checkInsertion, versionStr, self.currentInserion)
            except:
                logger.warn('Missing version for process ID {}'.format(self.currentInsertion))
        elif commandName == 'insert':
            if self.currentStatus == 100:
                versionStr = self.versionFromCommandMessage(interest.getName().get(command_idx+1))
                self.processIdToVersion[self.currentInsertion] = versionStr
                stats.insertDataForVersion(versionStr, {'insert_begin': now})
                self.loop.call_soon(self.checkInsertion, versionStr, self.currentInsertion)
            else:
                self.failureCount += 1
                self.loop.call_soon(self.kickRepo)
Exemplo n.º 30
0
class SongHandler:
    def __init__(self):

        self._device = "PC1"
        self._playPrefix = Name("/ndn/edu/ucla/remap/music/play")
        self.prefix = self._playPrefix.append(self._device)

        self._face = None
        self._loop = None

        self._keyChain = KeyChain()
        self._certificateName = self._keyChain.getDefaultCertificateName()

        self._repoCommandPrefix = "/example/repo/1"

        self.mp = MusicPlayer()
        #self._getFiles = []

    def start(self):
        self._loop = asyncio.get_event_loop()
        self._face = ThreadsafeFace(self._loop, "")
        self._face.setCommandSigningInfo(self._keyChain, self._certificateName)
        self._face.registerPrefix(self.prefix, self.onPlayingCommand,
                                  self.onRegisterFailed)

        try:
            self._loop.run_forever()
        except KeyboardInterrupt:
            sys.exit()
        finally:
            self.stop()

    def stop(self):
        self._loop.close()
        self._face.shutdown()
        sys.exit(1)

    def getOnset(self, musicName):
        otxt = musicName + str("-o")
        print otxt
        g = GetFile(self._repoCommandPrefix, otxt, self._face, self.getFreq,
                    musicName)
        g.oStream = open(musicName + str("-os.txt"), 'wb')
        g.start()

        #self._getFiles.append(g)

    def getFreq(self, musicName):
        ftxt = musicName + str("-f")
        print musicName, " get Freq called"
        g = GetFile(self._repoCommandPrefix, ftxt, self._face,
                    self.mp.play_music, musicName, False)
        g.oStream = open(musicName + str("-freq.txt"), 'wb')
        g.start()

        #self._getFiles.append(g)

    def signData(self, data):
        data.setSignature(Sha256WithRsaSignature())

    def onPlayingCommand(self, prefix, interest, transport, prefixId):

        interestName = Name(interest.getName())
        commandComponent = interest.getName().get(self.prefix.size())
        if commandComponent == Name.Component("stop"):
            pass
        if commandComponent == Name.Component("play"):
            pass
        else:
            songName = commandComponent.toEscapedString()

        songList = []
        songList = songName.split('%2C')

        for i in songList:
            fmusic = i + str("-music.mp3")
            print "started getting music file", i

            g = GetFile(self._repoCommandPrefix, i, self._face, self.getOnset,
                        i)

            g.oStream = open(fmusic, 'wb')
            g.start()

            #self._getFiles.append(g)

        d = Data(interest.getName())
        d.setContent("start to play: " + songName + "\n")
        encodedData = d.wireEncode()
        transport.send(encodedData.toBuffer())

    def onRegisterFailed(self, prefix):
        self.log.error("Could not register " + prefix.toUri())
        self.stop()
Exemplo n.º 31
0
 def start(self):
     self.loop =  asyncio.get_event_loop()
     self.face = ThreadsafeFace(self.loop, "")
     self.face.stopWhen(lambda:self.isCancelled)
     self.reissueInterest()
     self.loop.run_forever()
Exemplo n.º 32
0
class SongHandler:

	def __init__(self):

		self._device = "PC1"
		self._playPrefix = Name("/ndn/edu/ucla/remap/music/play")
		self.prefix = self._playPrefix.append(self._device)
		
		self._face = None
		self._loop = None
	
		self._keyChain = KeyChain()
		self._certificateName = self._keyChain.getDefaultCertificateName()

		self._repoCommandPrefix = "/example/repo/1"

		self.mp = MusicPlayer()
		#self._getFiles = []
		
	def start(self):
		self._loop = asyncio.get_event_loop()
		self._face = ThreadsafeFace(self._loop,"")
		self._face.setCommandSigningInfo(self._keyChain, self._certificateName)
		self._face.registerPrefix(self.prefix, self.onPlayingCommand, self.onRegisterFailed)
	
		try:
			self._loop.run_forever()
		except KeyboardInterrupt:
			sys.exit()
		finally:
			self.stop()

	def stop(self):
		self._loop.close()	
		self._face.shutdown()
		sys.exit(1)

	def getOnset(self, musicName):
		otxt = musicName + str("-o")
		print otxt
		g = GetFile(self._repoCommandPrefix, otxt, self._face, self.getFreq, musicName)
		g.oStream = open(musicName + str("-os.txt"), 'wb')
		g.start()
		
		#self._getFiles.append(g)

	def getFreq(self, musicName):
		ftxt = musicName + str("-f")
		print musicName, " get Freq called"
		g = GetFile(self._repoCommandPrefix, ftxt, self._face, self.mp.play_music, musicName, False)
		g.oStream = open(musicName + str("-freq.txt"),'wb')
		g.start()
		
		#self._getFiles.append(g)

	def signData(self, data):
		data.setSignature(Sha256WithRsaSignature())
	
	def onPlayingCommand(self, prefix, interest, transport, prefixId):
		
		interestName = Name(interest.getName())
		commandComponent = interest.getName().get(self.prefix.size())
		if commandComponent == Name.Component("stop"):
			pass
		if commandComponent == Name.Component("play"):
			pass
		else:
			songName = commandComponent.toEscapedString()
	    
		songList = []
		songList = songName.split('%2C')
	    
		for i in songList:
			fmusic = i + str("-music.mp3") 
			print "started getting music file", i
			
			g = GetFile(self._repoCommandPrefix, i, self._face, self.getOnset, i)
			
			g.oStream = open(fmusic,'wb')
			g.start()
			
			#self._getFiles.append(g)
			
		d = Data(interest.getName())
		d.setContent("start to play: " + songName + "\n")
		encodedData = d.wireEncode()
		transport.send(encodedData.toBuffer())	

	def onRegisterFailed(self, prefix):
		self.log.error("Could not register " + prefix.toUri())
		self.stop()
Exemplo n.º 33
0
class NdnRepoPing(object):
    """
     A repo is supposed to be notified of new data by the publisher. Since the 
     publisher doesn't know about this repo, I will 'manually' poke the repo to      insert data points.
    """
    def __init__(self, repoPrefix=None):
        super(NdnRepoPing, self).__init__()
        if repoPrefix is not None:
            self.repoPrefix = repoPrefix
        else:
            self.repoPrefix = Name('/test/repo')
        self.repoWatchNames = []
        self.log = logging.getLogger(str(self.__class__))
        h = logging.FileHandler('repo_ping.log')
        h.setFormatter(logging.Formatter(
            '%(asctime)-15s %(levelname)-8s %(funcName)s\n\t%(message)s'))
        self.log.addHandler(h)
        self.log.setLevel(logging.DEBUG)
        self.isStopped = True
        logging.getLogger('trollius').addHandler(h)

    def onDataReceived(self, interest, data):
        self.log.debug('Response to {}'.format(interest.getName()))
        responseMessage = RepoCommandResponseMessage()
        ProtobufTlv.decode(responseMessage, data.getContent())
        self.log.debug('Status code: {}'.format(
            responseMessage.response.status_code))

    def onTimeout(self, interest):
        self.log.info('Timed out on {}'.format(interest.getName()))

    def sendRepoInsertCommand(self, dataName):
        self.log.debug('Sending insert command for {}'.format(dataName))
        commandMessage = RepoCommandParameterMessage()
        command = commandMessage.command
        for component in dataName:
            command.name.components.append(str(component.getValue()))
        command.start_block_id = command.end_block_id = 0
        commandComponent = ProtobufTlv.encode(commandMessage)

        interestName = Name(self.repoPrefix).append('insert')
        interestName.append(commandComponent)
        interest = Interest(interestName)
        interest.setInterestLifetimeMilliseconds(4000)
        self.face.makeCommandInterest(interest)
        
        self.face.expressInterest(interest, self.onDataReceived, self.onTimeout)

    @asyncio.coroutine
    def sendNextInsertRequest(self):
        sleepTime = 60*15
        while True:
            for name in self.repoWatchNames:
                self.sendRepoInsertCommand(name)
            yield From(asyncio.sleep(sleepTime))

    def start(self):
        self.isStopped = False
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        self.face = ThreadsafeFace(self.loop, '')
        k = KeyChain()
        self.face.setCommandSigningInfo(k, k.getDefaultCertificateName())
        self.face.stopWhen(lambda:self.isStopped)
        try:
            self.loop.run_until_complete(self.sendNextInsertRequest())
        finally:
            self.face.shutdown()

    def stop(self):
        self.isStopped = True

    def addWatchName(self, newName):
        if newName not in self.repoWatchNames:
            self.repoWatchNames.append(Name(newName))
Exemplo n.º 34
0
class RegisterSongList(object):
    def __init__(self, prefix="/ndn/edu/ucla/remap/music/list"):

        logging.basicConfig()
        '''#这些log是干嘛的myIP="192.168.1.1",lightIP="192.168.1.50",
        self.log = logging.getLogger("RegisterSongList")
        self.log.setLevel(logging.DEBUG)
        sh = logging.StreamHandler()
        sh.setLevel(logging.DEBUG)
        self.log.addHandler(sh)
        fh = logging.FileHandler("RegisterSongList.log")
        fh.setLevel(logging.INFO)
        self.log.addHandler(fh)'''
        self.device = "PC3"
        self.deviceComponent = Name.Component(self.device)
        self.excludeDevice = None
        #self.songList = originalList

        #security?
        self.prefix = Name(prefix)
        self.changePrefix = Name("/ndn/edu/ucla/remap/music/storage")
        self.keychain = KeyChain()
        self.certificateName = self.keychain.getDefaultCertificateName()

        self.address = ""
        self._isStopped = True

    #self.payloadBuffer = []

    #self.kinetsender = KinetSender(myIP, playerIP,self.STRAND_SIZE*self.COLORS_PER_LIGHT)

    def start(self):
        print "reg start"
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, self.address)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.face.registerPrefix(self.prefix, self.onInterest,
                                 self.onRegisterFailed)
        self._isStopped = False
        self.face.stopWhen(lambda: self._isStopped)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:

            sys.exit()
        finally:
            self.stop()

    def stop(self):
        self.loop.close()
        #self.kinetsender.stop = True
        #self.kinetsender.complete.wait()
        self.face.shutdown()
        self.face = None
        sys.exit(1)

    def signData(self, data):
        data.setSignature(Sha256WithRsaSignature())
        #self.keychain.sign(data,self.certificateName)

    def onInterest(self, prefix, interest, transport, registeredPrefixId):
        print "received interest"
        initInterest = Name(interest.getName())
        print "interest name:", initInterest.toUri()
        #d = Data(interest.getName().getPrefix(prefix.size()+1))
        #self.excludeDevice = interest.getName().get(prefix.size())
        #initInterest = interest.getName()
        d = Data(interest.getName().append(self.deviceComponent))
        try:
            print "start to set data's content"

            currentString = ','.join(currentList)
            d.setContent("songList of " + self.device + ":" + currentString +
                         "\n")
            self.face.registerPrefix(self.changePrefix, self.onInterest,
                                     self.onRegisterFailed)

        except KeyboardInterrupt:
            print "key interrupt"
            sys.exit(1)
        except Exception as e:
            print e
            d.setContent("Bad command\n")
        finally:
            self.keychain.sign(d, self.certificateName)

        encodedData = d.wireEncode()
        transport.send(encodedData.toBuffer())
        print d.getName().toUri()
        print d.getContent()

        self.stop()
        '''print"remove register"
        self.face.removeRegisteredPrefix(registeredPrefixId)
        time.sleep(30)
        #sleep 30s which means user cannot update the song list twice within 1 minutes
	print"register again"
        self.face.registerPrefix(self.prefix, self.onInterest, self.onRegisterFailed)'''

    def onRegisterFailed(self, prefix):
        self.log.error("Could not register " + prefix.toUri())
        self.stop()
Exemplo n.º 35
0
 def __init__(self):
     self._loop = asyncio.get_event_loop()
     self._face = ThreadsafeFace(self._loop, "")
     self._keyChain = KeyChain()
     self._certificateName = self._keyChain.getDefaultCertificateName()
     self._face.setCommandSigningInfo(self._keyChain, self._certificateName)
Exemplo n.º 36
0
class RepoConsumer:
    TIMEOUT = 100
    def __init__(self, dataPrefix, interestLifetime=100, lastVersion=None, start=True):
        self.prefix = Name(dataPrefix)
        
        #used in the exclude to make sure we get new data only
        self.lastVersion = lastVersion

        self.face = None
        self.dataFormat = re.compile("\((\d+\.?\d*)\)") # data should start with a timestamp in 
        logFormat = '%(asctime)-10s %(message)s'
        self.logger = logging.getLogger('RepoConsumer')
        self.logger.setLevel(logging.DEBUG)
        self.logger.addHandler(logging.StreamHandler())
        fh = logging.FileHandler('repo_consumer.log', mode='w')
        fh.setLevel(logging.DEBUG)
        fh.setFormatter(logging.Formatter(logFormat))
        self.logger.addHandler(fh)
        self.createTiming = []
        self.receiveTiming = []
        self.timeouts = 0
        self.notReady = 0

        self.lastReceivedTime = 0
        self.lastCreatedTime = 0
        self.backoffCounter = 0
        
        self.interestLifetime = interestLifetime

        self.nextIssue = None
        self.loop = None

        self.isCancelled = False

    def start(self):
        self.loop =  asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, "")
        self.face.stopWhen(lambda:self.isCancelled)
        self.reissueInterest()
        self.loop.run_forever()

    def stop(self):
        self.loop.close()
        self.face.shutdown()
        self.loop = None
        self.face = None

    def onData(self, interest, data):
        now = time.time()
        # for now, assume there is a version appended to the interest
        nameLength = interest.getName().size()
        dataStr = data.getContent().toRawStr()
        try:
            lastComponent = data.getName().get(-1).toEscapedString()
            if str(lastComponent) == 'MISSING':
                self.notReady += 1
                #self.backoffCounter += 1
                logger.info('repo not ready')
                self.reissueInterest()
                return

            self.lastVersion = data.getName().get(nameLength)
            self.logger.debug(interest.getName().toUri() + ": version " + self.lastVersion.toEscapedString())
            match = self.dataFormat.match(data.getContent().toRawStr())
            ts = float(match.group(1))
            if self.lastReceivedTime != 0 and self.lastCreatedTime != 0:
                self.createTiming.append(now-self.lastReceivedTime)
                self.receiveTiming.append(now-self.lastCreatedTime)

            self.lastReceivedTime = now
            self.lastCreatedTime = ts
            self.logger.debug("Created: " + str(ts) +  ", received: " + str(now))
        except Exception as  e:
            self.logger.exception(str(e))
        #self.backoffCounter -= 1
        self.reissueInterest()

    def onTimeout(self, interest):
        self.logger.debug("timeout")
        self.timeouts += 1
        #self.backoffCounter += 1
        self.reissueInterest()

    def reissueInterest(self):
        BACKOFF_THRESHOLD = 10
        if self.backoffCounter > BACKOFF_THRESHOLD:
            self.TIMEOUT += 50
            self.backoffCounter = 0
            self.logger.debug('Backing off interval to ' + str(self.TIMEOUT))
        if self.backoffCounter < -BACKOFF_THRESHOLD:
            self.TIMEOUT -= 50
            self.backoffCounter = 0
            self.logger.debug('Reducing backoff interval to ' + str(self.TIMEOUT))
        if self.nextIssue is not None:
            now = time.clock()
            if self.nextIssue > now:
                pass
               # time.sleep(self.nextIssue-now)
        interest = Interest(Name(self.prefix))
        interest.setInterestLifetimeMilliseconds(self.interestLifetime)
        interest.setMustBeFresh(False)
        if self.lastVersion is not None:
            e = Exclude()
            e.appendAny()
            e.appendComponent(self.lastVersion)
            interest.setExclude(e)
        interest.setChildSelector(1) #rightmost == freshest
        self.face.expressInterest(interest, self.onData, self.onTimeout)
        self.nextIssue = time.clock()+self.TIMEOUT/2000

    def printStats(self):
        # the first value may have been sitting in the repo forever, so ignore the first time
        timing = self.createTiming
        self.logger.info('***** Statistics ***** ')
        if len(timing) > 1:
            self.logger.info('{1:3.2f}/{2:3.2f}/{3:3.2f} min/mean/max delay(creation)'.format(len(timing), min(timing), mean(timing), max(timing)))
        timing = self.receiveTiming
        if len(timing) > 1:
            self.logger.info('{1:3.2f}/{2:3.2f}/{3:3.2f} min/mean/max delay(receipt)'.format(len(timing), min(timing), mean(timing), max(timing)))
            self.logger.info('{} data requests satisfied'.format(len(timing)))
        self.logger.info('{} timeouts'.format(self.timeouts))
        self.logger.info('{} not ready responses'.format(self.notReady))
        self.logger.info('*'*22)
Exemplo n.º 37
0
class RegisterSongList(object):
    def __init__(self, prefix="/ndn/edu/ucla/remap/music/list"):

        logging.basicConfig()
        self.device = "PC1"
        self.deviceComponent = Name.Component(self.device)
        self.excludeDevice = None

        self.prefix = Name(prefix)
        self.changePrefix = Name("/ndn/edu/ucla/remap/music/storage")
        self.keychain = KeyChain()
        self.certificateName = self.keychain.getDefaultCertificateName()

        self.address = ""
        self._isStopped = True

    def start(self):
        print "reg start"
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, self.address)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.face.registerPrefix(self.prefix, self.onInterest,
                                 self.onRegisterFailed)
        self._isStopped = False
        self.face.stopWhen(lambda: self._isStopped)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:

            sys.exit()
        finally:
            self.stop()

    def stop(self):
        self.loop.close()
        self.face.shutdown()
        self.face = None
        sys.exit(1)

    def signData(self, data):
        data.setSignature(Sha256WithRsaSignature())

    def onInterest(self, prefix, interest, transport, registeredPrefixId):
        print "received interest"
        initInterest = Name(interest.getName())
        print "interest name:", initInterest.toUri()
        d = Data(interest.getName().append(self.deviceComponent))
        try:
            print "start to set data's content"

            currentString = ','.join(currentList)
            d.setContent("songList of " + self.device + ":" + currentString +
                         "\n")
            self.face.registerPrefix(self.changePrefix, self.onInterest,
                                     self.onRegisterFailed)

        except KeyboardInterrupt:
            print "key interrupt"
            sys.exit(1)
        except Exception as e:
            print e
            d.setContent("Bad command\n")
        finally:
            self.keychain.sign(d, self.certificateName)

        encodedData = d.wireEncode()
        transport.send(encodedData.toBuffer())
        print d.getName().toUri()
        print d.getContent()

        self.loop.close()

        self.face.shutdown()
        self.face = None

    def onRegisterFailed(self, prefix):
        self.log.error("Could not register " + prefix.toUri())
        self.stop()
Exemplo n.º 38
0
class RegisterSongList(object):


    def __init__(self, prefix="/ndn/edu/ucla/remap/music/list"):

	logging.basicConfig()        
	'''#这些log是干嘛的myIP="192.168.1.1",lightIP="192.168.1.50",
        self.log = logging.getLogger("RegisterSongList")
        self.log.setLevel(logging.DEBUG)
        sh = logging.StreamHandler()
        sh.setLevel(logging.DEBUG)
        self.log.addHandler(sh)
        fh = logging.FileHandler("RegisterSongList.log")
        fh.setLevel(logging.INFO)
        self.log.addHandler(fh)'''
    	self.device = "PC3"
    	self.deviceComponent = Name.Component(self.device)
	self.excludeDevice = None
    	#self.songList = originalList

        #security?
        self.prefix = Name(prefix)
	self.changePrefix = Name("/ndn/edu/ucla/remap/music/storage")
        self.keychain = KeyChain()
        self.certificateName = self.keychain.getDefaultCertificateName()

        self.address = ""
        self._isStopped = True
  
        #self.payloadBuffer = []

        #self.kinetsender = KinetSender(myIP, playerIP,self.STRAND_SIZE*self.COLORS_PER_LIGHT)




    
    def start(self):
	print "reg start"
	self.loop = asyncio.get_event_loop()
	self.face = ThreadsafeFace(self.loop,self.address)
	self.face.setCommandSigningInfo(self.keychain,self.certificateName)
        self.face.registerPrefix(self.prefix,self.onInterest,self.onRegisterFailed)
        self._isStopped = False
        self.face.stopWhen(lambda:self._isStopped)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:

            sys.exit()
        finally:
            self.stop()


    def stop(self):
        self.loop.close()
        #self.kinetsender.stop = True
        #self.kinetsender.complete.wait()         
        self.face.shutdown()
        self.face = None
        sys.exit(1)

    def signData(self,data):
	data.setSignature(Sha256WithRsaSignature())
	#self.keychain.sign(data,self.certificateName)

    def onInterest(self, prefix, interest, transport, registeredPrefixId):
	print "received interest"
        initInterest = Name(interest.getName())
        print "interest name:",initInterest.toUri()
        #d = Data(interest.getName().getPrefix(prefix.size()+1))
        #self.excludeDevice = interest.getName().get(prefix.size())
	#initInterest = interest.getName()
	d = Data(interest.getName().append(self.deviceComponent))
	try:
		print "start to set data's content"
                
		currentString = ','.join(currentList)
		d.setContent("songList of " +self.device+":"+currentString+ "\n")
		self.face.registerPrefix(self.changePrefix,self.onInterest,self.onRegisterFailed)	



	    

	except KeyboardInterrupt:
		print "key interrupt"
		sys.exit(1)
	except Exception as e:
		print e
		d.setContent("Bad command\n")
	finally:
		self.keychain.sign(d,self.certificateName)

	encodedData = d.wireEncode()
	transport.send(encodedData.toBuffer())
	print d.getName().toUri()
	print d.getContent()

	self.stop()
		
	'''print"remove register"
        self.face.removeRegisteredPrefix(registeredPrefixId)
        time.sleep(30)
        #sleep 30s which means user cannot update the song list twice within 1 minutes
	print"register again"
        self.face.registerPrefix(self.prefix, self.onInterest, self.onRegisterFailed)'''

    def onRegisterFailed(self, prefix):
        self.log.error("Could not register " + prefix.toUri())
        self.stop()
Exemplo n.º 39
0
class MCCPublisher:
    def __init__(self, dataPrefix, dataSuffix, keychain=None):
        self.currentInsertion = -1
        self.currentStatus = -1
        self.face = None
        self.loop = None
        self.dataName = Name(dataPrefix).append(dataSuffix)
        self.dataPrefix = Name(dataPrefix)

        if keychain is not None:
            self.keychain = keychain
        else:
            self.keychain = KeyChain()

        self.certificateName = self.keychain.getDefaultCertificateName()

        self.fakeSignature = Sha256WithRsaSignature()

        self.failureCount = 0
        self.successCount = 0

        self.dataCache = None

    def onRegisterFailed(self):
        logger.error("Could not register data publishing face!")
        self.stop()

    def stop(self):
        self.loop.close()
        self.face.shutdown()

    def generateVersionedName(self):
        fullName = Name(self.dataName)
        # currently we need to provide the version ourselves when we
        # poke the repo
        ts = int(time.time()*1000)
        fullName.appendVersion(int(ts))
        return fullName

    def generateData(self, baseName):
        '''
           This appends the segment number to the data name, since repo-ng tends to expect it
        '''
        # just make up some data and return it
        ts = (time.time())
        segmentId = 0 # compatible with repo-ng test: may change to test segmented data

        versionStr = baseName.get(-1).toEscapedString()
        dataName = Name(baseName)
        dataName.appendSegment(segmentId)

        d = Data(dataName)
        content = "(" + str(ts) +  ") Data named " + dataName.toUri()
        d.setContent(content)
        d.getMetaInfo().setFinalBlockID(segmentId)
        d.getMetaInfo().setFreshnessPeriod(-1)
        if shouldSign:
            self.keychain.sign(d, self.certificateName)
        else:
            d.setSignature(self.fakeSignature)

        stats.insertDataForVersion(versionStr, {'publish_time':time.time()})
        logger.debug('Publishing: '+d.getName().toUri())
        return d

    def onTimeout(self, prefix):
        logger.warn('Timeout waiting for '+prefix.toUri())

    @asyncio.coroutine
    def insertNewVersion(self, interval=20):
        #while True:
            newVersion = self.generateVersionedName()
            versionStr = newVersion.get(-1).toEscapedString()
            logger.info('Inserting: '+versionStr)
            stats.insertDataForVersion(versionStr, {'insert_request':time.time()})

            newData = self.generateData(newVersion)

            self.dataCache.add(newData)
            stats.insertDataForVersion(versionStr, {'insert_complete':time.time()})
            yield From (self.insertNewVersion())

    def start(self):
        self.loop = asyncio.new_event_loop()
        self.face = ThreadsafeFace(self.loop, "")
        self.dataCache = MemoryContentCache(self.face, 100)

        asyncio.set_event_loop(self.loop)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)

        self.dataCache.registerPrefix(self.dataPrefix, self.onRegisterFailed)
        self.loop.run_until_complete(self.insertNewVersion())
Exemplo n.º 40
0
    
    musicOutputFile = "PC3-received-2.txt"
    g1.oStream = open(musicOutputFile, 'wb')
    g1.start()

def callback2():
    print "it works again"

if __name__ == '__main__':
    logging.basicConfig()
    #songList = ['Hotel California', 'river flows in you', 'simple way', 'star', 'mozart', 'yellow', 'canon', 'a comm amour', 'RICHA', 'merry christmas', 'love story', 'juliet', 'geqian', 'nocturne', 'RICHA1111', 'canon1', 'nocturne1', 'house_lo', 'house_lo']
    #for i in songList:
    dataName = "/clear"
    repoCommandPrefix = "/example/repo/1"
    
    loop = asyncio.get_event_loop()
    face = ThreadsafeFace(loop, "")
    keyChain = KeyChain()
    certificateName = keyChain.getDefaultCertificateName()
    face.setCommandSigningInfo(keyChain, certificateName)
        
    g = GetFile(repoCommandPrefix, dataName, face, callbackFunc(repoCommandPrefix, "/clear-f", face, callback2))
    
    musicOutputFile = "PC3-received.txt"
    g.oStream = open(musicOutputFile, 'wb')
    g.start()
    
    
    print "it works"
    loop.run_forever()
Exemplo n.º 41
0
class LightController():
    shouldSign = False
    COLORS_PER_LIGHT = 3
    STRAND_SIZE = 50
    #mengchen: let's make the lighting lits only a half every time
    #HALF_STRAND_SIZE = 25
    def __init__(self, nStrands=1, myIP="192.168.1.1", lightIP="192.168.1.50", prefix="/testlight"):
        self.log = logging.getLogger("LightController")
        self.log.setLevel(logging.DEBUG)
        sh = logging.StreamHandler()
        sh.setLevel(logging.DEBUG)
        self.log.addHandler(sh)
        fh = logging.FileHandler("LightController.log")
        fh.setLevel(logging.INFO)
        self.log.addHandler(fh)

        self.payloadBuffer = [[0]*self.STRAND_SIZE*self.COLORS_PER_LIGHT for n in range(nStrands)]

        self.kinetsender = KinetSender(myIP, lightIP, nStrands, self.STRAND_SIZE*self.COLORS_PER_LIGHT)
        self.prefix = Name(prefix)
        self.keychain = KeyChain()

        self.address = ""
        self._isStopped = True

        self.lightState = False
        #mengchen: let's make the lighting lits only a half every time
        #self.uphalf =  True
        self.HALF_STRAND_SIZE = 25       
        self.certificateName = self.keychain.getDefaultCertificateName()
        self.receiveFile = open('interestReceiveFile', 'w')

    def unix_time_now(self):
        epoch = datetime.datetime.utcfromtimestamp(0)
        delta = datetime.datetime.utcnow() - epoch
        return delta.total_seconds() * 1000.0
    
    # XXX: we should get a thread for this or something!
    def start(self):

        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, self.address)
        self.face.setCommandSigningInfo(self.keychain, self.certificateName)
        self.face.registerPrefix(self.prefix, self.onLightingCommand, self.onRegisterFailed)
        self._isStopped = False
        self.face.stopWhen(lambda:self._isStopped)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            #self.stop()
            #print "key interrupt in run_forever"
            sys.exit()
        finally:
            #print "executing finally"
            self.stop()


    def stop(self):
        self.loop.close()
        self.kinetsender.stop = True
        #print "before wait"
        #self.kinetsender.complete.set
        #self.kinetsender.complete.wait()         
        self.face.shutdown()
        self.face = None
        #print "sys exit"
        self.receiveFile.close()
        sys.exit(1)

    def signData(self, data):
        if LightController.shouldSign:
            self.keychain.sign(data, self.certificateName)
        else:
            data.setSignature(Sha256WithRsaSignature())

    def setPayloadColor(self, strand, color):
    # will expand this to allow the repeats, etc
       # if self.uphalf and not self.lightState:
        #    self.uphalf = False
         #   self.payloadBuffer[strand] = [int(color.r)&0xff, int(color.g)&0xff, int(color.b)&0xff]*self.HALF_STRAND_SIZE+[int(0)&0xff, int(0)&0xff, int(0)&0xff]*self.HALF_STRAND_SIZE
        #if not self.uphalf and self.lightState :
         #   self.uphalf = True
            self.payloadBuffer[strand] = [int(color.r)&0xff, int(color.g)&0xff, int(color.b)&0xff]*self.STRAND_SIZE
            
    def onLightingCommand(self, prefix, interest, transport, prefixId):
        #print datetime.datetime.now()
        self.receiveFile.write('{0:f}'.format(self.unix_time_now()) + '\n')
        interestName = Name(interest.getName())
        #interstname: /ndn/ucla.edu/sculptures/ai_bus/lights/setRGB/%83%0D%84%0B%87%09%89%01%04%8A%01%01%8B%01%01
        #d: <pyndn.data.Data object at 0xb64825d0>
        print "interstname", interestName.toUri()
        d = Data(interest.getName())
        # get the command parameters from the name
        try:
            commandComponent = interest.getName().get(prefix.size())
            #print commandComponent.toEscapedString():setRGB
            #print "prefix ",prefix.toUri():/ndn/ucla.edu/sculpture/ai_bus/lights
            #print "get name",interest.getName().toUri()
            commandParams = interest.getName().get(prefix.size()+1)
            #print "commandParams ",commandParams:%83%0D%84%0B%87%09%89%01%04%8A%01%01%8B%01%01

            lightingCommand = LightCommandMessage()
            ProtobufTlv.decode(lightingCommand, commandParams.getValue())
            #self.log.info("Command: " + commandComponent.toEscapedString())
            requestedColor = lightingCommand.command.pattern.colors[0] 
            colorStr = str((requestedColor.r, requestedColor.g, requestedColor.b))
            #self.log.info("Requested color: " + colorStr)
            self.setPayloadColor(0, requestedColor)
            
            self.lightState = not self.lightState
            if self.lightState:
                print "Off"
            else:
                print "On"
            
            #print requestedColor
            
            self.sendLightPayload(1)
            d.setContent("Gotcha: " + colorStr+ "\n")
        except KeyboardInterrupt:
            print "key interrupt"
            sys.exit(1)
        except Exception as e:
            print e
            d.setContent("Bad command\n")
        finally:
            d.getMetaInfo().setFinalBlockID(0)
            self.signData(d)

        encodedData = d.wireEncode()
        transport.send(encodedData.toBuffer())

    def onRegisterFailed(self, prefix):
        self.log.error("Could not register " + prefix.toUri())
        self.stop()

    def sendLightPayload(self, port):
        # print port
        # print self.payloadBuffer[port-1]
        self.kinetsender.setPayload(port, self.payloadBuffer[port-1])
Exemplo n.º 42
0
class SongHandler:

    def __init__(self):

        self._device = "PC1"
        self._playPrefix = Name("/ndn/edu/ucla/remap/music/play")
	self.prefix = self._playPrefix.append(self._device)
        self._face = None
        self._loop = None

	self.thread = None
        
        self._keyChain = KeyChain()
        self._certificateName = self._keyChain.getDefaultCertificateName()

        self._repoCommandPrefix = "/example/repo/1"

	self.song = ""
	self.ftxt = ""
	self.ffreq = ""

	self.songList = ""
	self.mp = MusicPlayer()
	self.config = RawConfigParser()
	self.config.read('config.cfg')
	self.s = LightMessenger(self.config)

	self.q = Queue.Queue()
	

    def start(self):
        self._loop = asyncio.get_event_loop()
        self._face = ThreadsafeFace(self._loop,"")
        self._face.setCommandSigningInfo(self._keyChain, self._certificateName)
        self._face.registerPrefix(self.prefix, self.onPlayingCommand, self.onRegisterFailed)
	print "after register prefix"
        try:
            self._loop.run_forever()
        except KeyboardInterrupt:
            sys.exit()
        finally:
            self.stop()

    def stop(self):
        self._loop.close()        
        self._face.shutdown()
        sys.exit(1)

    def playFunction(self):

	    txt = open(self.ftxt)
	    print "open txt successfully",self.ftxt
	
		#collect the onset duration
	    osDur = [0.0]
	    freq = []
	    data = [float(line.split()[0])for line in txt]
	
	    for i in data:
	    	osDur.append(i)
	    txt.close()
	    txt = open(self.ffreq)
	    print "open txt successfully",self.ffreq
	    data = [float(line.split()[1])for line in txt]
	    print "dasfdaaaa"
	    for j in data:
		freq.append(j)
	    avefq = int(sum(freq)/len(freq))  
	    print avefq  	
	    txt.close()
	    g=(avefq-100)/10
	    r=avefq/30
	    b=(100-avefq)/10
	    startingColors = [int((15+r)/1.5),int((10+g)/1.5), int((10+b)/1.5)]
	    for i in range(0,3):
		if startingColors[i]<0:
			startingColors[i]=6
	    #startingColors = [5,5,5]
	    self.q.put(self.song+str("-music.mp3") )
	    print "MusicPlayer.isPlaying",MusicPlayer.isPlaying
	    if not MusicPlayer.isPlaying:
    	    	self.thread.start() 
		#MusicPlayer.isPlaying = True 
	      
	    self.s.start(osDur,startingColors)

    def getOnset(self):
	print "getonset"
	otxt = self.song+str("-o")
	print otxt
	g = GetFile(self._repoCommandPrefix, otxt, self._face, self.getFreq)
	g.oStream = open(self.song+str("-os.txt"),'wb')    
	g.start()

    def getFreq(self):
	print "getfreq"
	ftxt = self.song+str("-f")
	g = GetFile(self._repoCommandPrefix, ftxt, self._face, self.playFunction)
	g.oStream = open(self.song+str("-freq.txt"),'wb')    
	g.start()

    def signData(self, data):
        data.setSignature(Sha256WithRsaSignature())
        

    def onPlayingCommand(self, prefix, interest, transport, prefixId):
	print "receive interest"
        interestName = Name(interest.getName())
        commandComponent = interest.getName().get(self.prefix.size())
        if commandComponent == Name.Component("stop"):
            pass
        if commandComponent == Name.Component("play"):
            pass
        else:
            songName = commandComponent.toEscapedString()
	    print songName
	    songList = []
	    songList = songName.split('%2C')
	    print "songlist and its len",songList,len(songList)
	    for i in songList:
		self.song = i
            	fmusic = i+str("-music.mp3") 
		self.ftxt = i + str("-os.txt")
		self.ffreq = i + str("-freq.txt")
		print "FMUSIC:",fmusic 
		  
	    	self.thread = threading.Thread(target = self.mp.play_music, args = (fmusic,songList,self.q,))
	    	self.thread.daemon = True
            	g = GetFile(self._repoCommandPrefix, i, self._face, self.getOnset)
		#g = GetFile(self._repoCommandPrefix, ftxt, self._face, self.lightFunction)
            	g.oStream = open(fmusic,'wb')
            	g.start()
	   
		
	
	d = Data(interest.getName())
	d.setContent("start to play: " + songName + "\n")
	encodedData = d.wireEncode()
	transport.send(encodedData.toBuffer())	

        
            
    def onRegisterFailed(self, prefix):
        self.log.error("Could not register " + prefix.toUri())
        self.stop()
Exemplo n.º 43
0
        self.issueSongCommand()


def runForever(loop):
    try:
        loop.run_forever()
    finally:
        sys.exit()


if __name__ == '__main__':

    skeychain = KeyChain()
    scertificateName = skeychain.getDefaultCertificateName()
    sloop = asyncio.get_event_loop()
    sface = ThreadsafeFace(sloop, "")

    sface.setCommandSigningInfo(skeychain, scertificateName)

    t = threading.Thread(target=runForever, args=(sloop, ))
    t.daemon = True
    t.start()

    #obtaining song list
    lq = ListRequiry(skeychain, sloop, sface)
    lq.start()
    songList = []
    songList = lq.onListTimeout()
    #wait for 10 sec
    time.sleep(10)
    #order song
Exemplo n.º 44
0
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 = IotIdentityStorage()
        self._identityManager = IotIdentityManager(self._identityStorage)
        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
        self._instanceSerial = None

        # waiting devices register this prefix and respond to discovery
        # or configuration interest
        self._hubPrefix = Name('/localhop/configure')

    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._policyManager.getDeviceIdentity())
        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()
Exemplo n.º 45
0
class IotConsole(object):
    """
    This uses the controller's credentials to provide a management interface
    to the user.
    It does not go through the security handshake (as it should be run on the
    same device as the controller) and so does not inherit from the BaseNode.
    """
    def __init__(self, networkName, nodeName):
        super(IotConsole, self).__init__()

        self.deviceSuffix = Name(nodeName)
        self.networkPrefix = Name(networkName)
        self.prefix = Name(self.networkPrefix).append(self.deviceSuffix)

        self._identityStorage = IotIdentityStorage()
        self._policyManager = IotPolicyManager(self._identityStorage)
        self._identityManager = IotIdentityManager(self._identityStorage)
        self._keyChain = KeyChain(self._identityManager, self._policyManager)

        self._policyManager.setEnvironmentPrefix(self.networkPrefix)
        self._policyManager.setTrustRootIdentity(self.prefix)
        self._policyManager.setDeviceIdentity(self.prefix)
        self._policyManager.updateTrustRules()

        self.foundCommands = {}
        self.unconfiguredDevices = []

        # TODO: use xDialog in XWindows
        self.ui = Dialog(backtitle='NDN IoT User Console', height=18, width=78)

        trolliusLogger = logging.getLogger('trollius')
        trolliusLogger.addHandler(logging.StreamHandler())

    def start(self):
        """
        Start up the UI
        """
        self.loop = asyncio.get_event_loop()
        self.face = ThreadsafeFace(self.loop, '')

        controllerCertificateName = self._identityStorage.getDefaultCertificateNameForIdentity(
            self.prefix)
        self.face.setCommandSigningInfo(self._keyChain,
                                        controllerCertificateName)
        self._keyChain.setFace(
            self.face)  # shouldn't be necessarym but doesn't hurt

        self._isStopped = False
        self.face.stopWhen(lambda: self._isStopped)

        self.loop.call_soon(self.displayMenu)
        try:
            self.loop.run_forever()
        except KeyboardInterrupt:
            pass
        except Exception as e:
            print(e)
            #self.log('Exception', e)
        finally:
            self._isStopped = True

    def stop(self):
        self._isStopped = True

#######
# GUI
#######

    def displayMenu(self):

        menuOptions = OrderedDict([('List network services',
                                    self.listCommands),
                                   ('Pair a device', self.pairDevice),
                                   ('Express interest', self.expressInterest),
                                   ('Quit', self.stop)])
        (retCode, retStr) = self.ui.mainMenu('Main Menu', menuOptions.keys())

        if retCode == Dialog.DIALOG_ESC or retCode == Dialog.DIALOG_CANCEL:
            # TODO: ask if you're sure you want to quit
            self.stop()
        if retCode == Dialog.DIALOG_OK:
            menuOptions[retStr]()

#######
# List all commands
######

    def listCommands(self):
        self._requestDeviceList(self._showCommandList, self.displayMenu)

    def _requestDeviceList(self, successCallback, timeoutCallback):
        self.ui.alert('Requesting services list...', False)
        interestName = Name(self.prefix).append('listCommands')
        interest = Interest(interestName)
        interest.setInterestLifetimeMilliseconds(3000)
        #self.face.makeCommandInterest(interest)
        self.face.expressInterest(
            interest, self._makeOnCommandListCallback(successCallback),
            self._makeOnCommandListTimeoutCallback(timeoutCallback))

    def _makeOnCommandListTimeoutCallback(self, callback):
        def onCommandListTimeout(interest):
            self.ui.alert('Timed out waiting for services list')
            self.loop.call_soon(callback)

        return onCommandListTimeout

    def _makeOnCommandListCallback(self, callback):
        def onCommandListReceived(interest, data):
            try:
                commandInfo = json.loads(str(data.getContent()))
            except:
                self.ui.alert(
                    'An error occured while reading the services list')
                self.loop.call_soon(self.displayMenu)
            else:
                self.foundCommands = commandInfo
                self.loop.call_soon(callback)

        return onCommandListReceived

    def _showCommandList(self):
        try:
            commandList = []
            for capability, commands in self.foundCommands.items():
                commandList.append('\Z1{}:'.format(capability))
                for info in commands:
                    signingStr = 'signed' if info['signed'] else 'unsigned'
                    commandList.append('\Z0\t{} ({})'.format(
                        info['name'], signingStr))
                commandList.append('')

            if len(commandList) == 0:
                # should not happen
                commandList = ['----NONE----']
            allCommands = '\n'.join(commandList)
            oldTitle = self.ui.title
            self.ui.title = 'Available services'
            self.ui.alert(allCommands, preExtra=['--colors'])
            self.ui.title = oldTitle
            #self.ui.menu('Available services', commandList, prefix='', extras=['--no-cancel'])
        finally:
            self.loop.call_soon(self.displayMenu)

#######
# New device
######

    def pairDevice(self):
        self._scanForUnconfiguredDevices()

    def _enterPairingInfo(self, serial, pin='', newName=''):
        fields = [
            Dialog.FormField('PIN', pin),
            Dialog.FormField('Device name', newName)
        ]
        (retCode, retList) = self.ui.form('Pairing device {}'.format(serial),
                                          fields)
        if retCode == Dialog.DIALOG_OK:
            pin, newName = retList
            if len(pin) == 0 or len(newName) == 0:
                self.ui.alert('All fields are required')
                self.loop.call_soon(self._enterPairingInfo, serial, pin,
                                    newName)
            else:
                try:
                    pinBytes = pin.decode('hex')
                except TypeError:
                    self.ui.alert('Pin is invalid')
                    self.loop.call_soon(self._enterPairingInfo, serial, pin,
                                        newName)
                else:
                    self._addDeviceToNetwork(serial, newName,
                                             pin.decode('hex'))
        elif retCode == Dialog.DIALOG_CANCEL or retCode == Dialog.DIALOG_ESC:
            self.loop.call_soon(self._showConfigurationList)

    def _showConfigurationList(self):
        foundDevices = self.unconfiguredDevices[:]
        emptyStr = '----NONE----'
        if len(foundDevices) == 0:
            foundDevices.append(emptyStr)
        retCode, retStr = self.ui.menu('Select a device to configure',
                                       foundDevices,
                                       preExtras=[
                                           '--ok-label', 'Configure',
                                           '--extra-button', '--extra-label',
                                           'Refresh'
                                       ])
        if retCode == Dialog.DIALOG_CANCEL or retCode == Dialog.DIALOG_ESC:
            self.loop.call_soon(self.displayMenu)
        elif retCode == Dialog.DIALOG_EXTRA:
            self.loop.call_soon(self._scanForUnconfiguredDevices)
        elif retCode == Dialog.DIALOG_OK and retStr != emptyStr:
            self.loop.call_soon(self._enterPairingInfo, retStr)
        else:
            self.loop.call_soon(self._showConfigurationList)

    def _scanForUnconfiguredDevices(self):
        # unconfigured devices should register '/localhop/configure'
        # we keep asking for unconfigured devices until we stop getting replies

        foundDevices = []

        self.ui.alert('Scanning for unconfigured devices...', False)

        def onDeviceTimeout(interest):
            # assume we're done - everyone is excluded
            self.unconfiguredDevices = foundDevices
            self.loop.call_soon(self._showConfigurationList)

        def onDeviceResponse(interest, data):
            updatedInterest = Interest(interest)
            deviceSerial = str(data.getContent())
            if len(deviceSerial) > 0:
                foundDevices.append(deviceSerial)
                updatedInterest.getExclude().appendComponent(
                    Name.Component(deviceSerial))
            # else ignore the malformed response
            self.face.expressInterest(updatedInterest, onDeviceResponse,
                                      onDeviceTimeout)

        interest = Interest(Name('/localhop/configure'))
        interest.setInterestLifetimeMilliseconds(2000)
        self.face.expressInterest(interest, onDeviceResponse, onDeviceTimeout)

    def _addDeviceToNetwork(self, serial, suffix, pin):
        self.ui.alert('Sending pairing info to gateway...', False)
        # we must encrypt this so no one can see the pin!
        message = DevicePairingInfoMessage()
        message.info.deviceSuffix = suffix
        message.info.deviceSerial = serial
        message.info.devicePin = pin
        rawBytes = ProtobufTlv.encode(message)
        encryptedBytes = self._identityManager.encryptForIdentity(
            rawBytes, self.prefix)
        encodedBytes = base64.urlsafe_b64encode(str(encryptedBytes))
        interestName = Name(
            self.prefix).append('addDevice').append(encodedBytes)
        interest = Interest(interestName)
        # todo: have the controller register this console as a listener
        # and update it with pairing status
        interest.setInterestLifetimeMilliseconds(5000)
        self.face.makeCommandInterest(interest)

        self.face.expressInterest(interest, self._onAddDeviceResponse,
                                  self._onAddDeviceTimeout)

    def _onAddDeviceResponse(self, interest, data):
        try:
            responseCode = int(str(data.getContent()))
            if responseCode == 202:
                self.ui.alert('Gateway received pairing info')
            else:
                self.ui.alert('Error encountered while sending pairing info')
        except:
            self.ui.alert('Exception encountered while decoding gateway reply')
        finally:
            self.loop.call_soon(self.displayMenu)

    def _onAddDeviceTimeout(self, interest):
        self.ui.alert('Timed out sending pairing info to gateway')
        self.loop.call_soon(self.displayMenu)


######
# Express interest
#####

    def expressInterest(self):
        if len(self.foundCommands) == 0:
            self._requestDeviceList(self._showInterestMenu,
                                    self._showInterestMenu)
        else:
            self.loop.call_soon(self._showInterestMenu)

    def _showInterestMenu(self):
        # display a menu of all available interests, on selection allow user to
        # (1) extend it
        # (2) send it signed/unsigned
        # NOTE: should it add custom ones to the list?
        commandSet = set()
        wildcard = '<Enter Interest Name>'
        try:
            for commands in self.foundCommands.values():
                commandSet.update([c['name'] for c in commands])
            commandList = list(commandSet)
            commandList.append(wildcard)
            (returnCode, returnStr) = self.ui.menu('Choose a command',
                                                   commandList,
                                                   prefix=' ')
            if returnCode == Dialog.DIALOG_OK:
                if returnStr == wildcard:
                    returnStr = self.networkPrefix.toUri()
                self.loop.call_soon(self._expressCustomInterest, returnStr)
            else:
                self.loop.call_soon(self.displayMenu)
        except:
            self.loop.call_soon(self.displayMenu)

    def _expressCustomInterest(self, interestName):
        #TODO: make this a form, add timeout field
        try:
            handled = False
            (returnCode,
             returnStr) = self.ui.prompt('Send interest',
                                         interestName,
                                         preExtra=[
                                             '--extra-button', '--extra-label',
                                             'Signed', '--ok-label', 'Unsigned'
                                         ])
            if returnCode == Dialog.DIALOG_ESC or returnCode == Dialog.DIALOG_CANCEL:
                self.loop.call_soon(self.expressInterest)
            else:
                interestName = Name(returnStr)
                doSigned = (returnCode == Dialog.DIALOG_EXTRA)
                interest = Interest(interestName)
                interest.setInterestLifetimeMilliseconds(5000)
                interest.setChildSelector(1)
                interest.setMustBeFresh(True)
                if (doSigned):
                    self.face.makeCommandInterest(interest)
                self.ui.alert(
                    'Waiting for response to {}'.format(interestName.toUri()),
                    False)
                self.face.expressInterest(interest, self.onDataReceived,
                                          self.onInterestTimeout)
        except:
            self.loop.call_soon(self.expressInterest)

    def onInterestTimeout(self, interest):
        try:
            self.ui.alert('Interest timed out:\n{}'.format(
                interest.getName().toUri()))
        except:
            self.ui.alert('Interest timed out')
        finally:
            self.loop.call_soon(self.expressInterest)

    def onDataReceived(self, interest, data):
        try:
            dataString = '{}\n\n'.format(data.getName().toUri())
            dataString += 'Contents:\n{}'.format(
                repr(data.getContent().toRawStr()))
            self.ui.alert(dataString)
        except:
            self.ui.alert('Exception occured displaying data contents')
        finally:
            self.loop.call_soon(self.expressInterest)