示例#1
0
 def __init__(self, arg1 = None, arg2 = None):
     if arg1 == None or Common.typeIsString(arg1):
         filePath = ""
         if arg1 == None and arg2 == None:
             # Check if we can connect using UnixSocket.
             tryFilePath = "/var/run/nfd.sock"
             # Use listdir because isfile doesn't see socket file types.
             if  (os.path.basename(tryFilePath) in 
                  os.listdir(os.path.dirname(tryFilePath))):
                 filePath = tryFilePath
             else:
                 tryFilePath = "/tmp/.ndnd.sock"
                 if  (os.path.basename(tryFilePath) in 
                      os.listdir(os.path.dirname(tryFilePath))):
                     filePath = tryFilePath
         
         if filePath == "":
             transport = TcpTransport()
             host = arg1 if arg1 != None else "localhost"
             connectionInfo = TcpTransport.ConnectionInfo(
               host, arg2 if type(arg2) is int else 6363)
         else:
             transport = UnixTransport()
             connectionInfo = UnixTransport.ConnectionInfo(filePath)
     else:
         transport = arg1
         connectionInfo = arg2
         
     self._node = Node(transport, connectionInfo)
     self._commandKeyChain = None
     self._commandCertificateName = Name()
示例#2
0
文件: face.py 项目: cawka/PyNDN2
    def __init__(self, arg1, arg2 = None):
        if type(arg1) is str:
            transport = TcpTransport()
            connectionInfo = TcpTransport.ConnectionInfo(
              arg1, arg2 if type(arg2) is int else 6363)
        else:
            transport = arg1
            connectionInfo = arg2

        self._node = Node(transport, connectionInfo)
示例#3
0
文件: face.py 项目: ISHITADG/PyNDN2
    def __init__(self, arg1=None, arg2=None):
        if arg1 == None or Common.typeIsString(arg1):
            filePath = ""
            if arg1 == None and arg2 == None:
                # Check if we can connect using UnixSocket.
                filePath = self._getUnixSocketFilePathForLocalhost()

            if filePath == "":
                transport = TcpTransport()
                host = arg1 if arg1 != None else "localhost"
                connectionInfo = TcpTransport.ConnectionInfo(
                    host, arg2 if type(arg2) is int else 6363)
            else:
                transport = UnixTransport()
                connectionInfo = UnixTransport.ConnectionInfo(filePath)
        else:
            transport = arg1
            connectionInfo = arg2

        self._node = Node(transport, connectionInfo)
        self._commandKeyChain = None
        self._commandCertificateName = Name()
示例#4
0
    def putNack(self, interest, networkNack):
        """
        Override to use the event loop given to the constructor to schedule
        putData to be called in a thread-safe manner. See
        Face.putData for calling details.
        """
        # Check the encoding size here so that the error message happens before
        # dispatch.
        encoding = Node._encodeLpNack(interest, networkNack)
        if encoding.size() > self.getMaxNdnPacketSize():
            raise RuntimeError(
                "The encoded Nack packet size exceeds the maximum limit getMaxNdnPacketSize()"
            )

        self._loop.call_soon_threadsafe(
            super(ThreadsafeFace, self).putNack, interest, networkNack)
示例#5
0
def nfdRegisterPrefix(self, registeredPrefixId, prefix, onInterest,
                      onRegisterFailed, onRegisterSuccess, flags,
                      commandKeyChain, commandCertificateName, face):
    """
    Do the work of registerPrefix to register with NFD.
        :param int registeredPrefixId: The getNextEntryId() which registerPrefix
      got so it could return it to the caller. If this is 0, then don't add
  to _registeredPrefixTable (assuming it has already been done).
    """
    if commandKeyChain == None:
        raise RuntimeError(
            "registerPrefix: The command KeyChain has not been set. You must call setCommandSigningInfo."
        )
    if commandCertificateName.size() == 0:
        raise RuntimeError(
            "registerPrefix: The command certificate name has not been set. You must call setCommandSigningInfo."
        )

    controlParameters = ControlParameters()
    controlParameters.setName(prefix)
    controlParameters.setForwardingFlags(flags)
    controlParameters.setOrigin(65)

    commandInterest = Interest()

    if self.isLocal():
        commandInterest.setName(Name("/localhost/nfd/rib/register"))
        # The interest is answered by the local host, so set a short timeout.
        commandInterest.setInterestLifetimeMilliseconds(2000.0)
    else:
        commandInterest.setName(Name("/localhop/nfd/rib/register"))
        # The host is remote, so set a longer timeout.
        commandInterest.setInterestLifetimeMilliseconds(4000.0)

    # NFD only accepts TlvWireFormat packets.
    commandInterest.getName().append(
        controlParameters.wireEncode(TlvWireFormat.get()))
    self.makeCommandInterest(commandInterest, commandKeyChain,
                             commandCertificateName, TlvWireFormat.get())

    # Send the registration interest.
    response = Node._RegisterResponse(prefix, onRegisterFailed,
                                      onRegisterSuccess, registeredPrefixId,
                                      self, onInterest, face)
    self.expressInterest(self.getNextEntryId(), commandInterest,
                         response.onData, response.onTimeout, None,
                         TlvWireFormat.get(), face)
示例#6
0
文件: face.py 项目: named-data/PyNDN2
    def __init__(self, arg1 = None, arg2 = None):
        if arg1 == None or Common.typeIsString(arg1):
            filePath = ""
            if arg1 == None and arg2 == None:
                # Check if we can connect using UnixSocket.
                filePath = self._getUnixSocketFilePathForLocalhost()

            if filePath == "":
                transport = TcpTransport()
                host = arg1 if arg1 != None else "localhost"
                connectionInfo = TcpTransport.ConnectionInfo(
                  host, arg2 if type(arg2) is int else 6363)
            else:
                transport = UnixTransport()
                connectionInfo = UnixTransport.ConnectionInfo(filePath)
        else:
            transport = arg1
            connectionInfo = arg2

        self._node = Node(transport, connectionInfo)
        self._commandKeyChain = None
        self._commandCertificateName = Name()
示例#7
0
文件: face.py 项目: ISHITADG/PyNDN2
class Face(object):
    """
    Create a new Face for communication with an NDN hub.  This constructor
    has the forms Face(), Face(transport, connectionInfo) or
    Face(host, port). If the default Face() constructor is used, if the
    forwarder's Unix socket file exists then connect using UnixTransport,
    otherwise connect to "localhost" on port 6363 using TcpTransport.

    :param Transport transport: An object of a subclass of Transport used for
      communication.
    :param Transport.ConnectionInfo connectionInfo: An object of a subclass of
      Transport.ConnectionInfo to be used to connect to the transport.
    :param str host: In the Face(host, port) form of the constructor, host is
      the host of the NDN hub to connect using TcpTransport.
    :param int port: (optional) In the Face(host, port) form of the constructor,
      port is the port of the NDN hub. If omitted. use 6363.
    """
    def __init__(self, arg1=None, arg2=None):
        if arg1 == None or Common.typeIsString(arg1):
            filePath = ""
            if arg1 == None and arg2 == None:
                # Check if we can connect using UnixSocket.
                filePath = self._getUnixSocketFilePathForLocalhost()

            if filePath == "":
                transport = TcpTransport()
                host = arg1 if arg1 != None else "localhost"
                connectionInfo = TcpTransport.ConnectionInfo(
                    host, arg2 if type(arg2) is int else 6363)
            else:
                transport = UnixTransport()
                connectionInfo = UnixTransport.ConnectionInfo(filePath)
        else:
            transport = arg1
            connectionInfo = arg2

        self._node = Node(transport, connectionInfo)
        self._commandKeyChain = None
        self._commandCertificateName = Name()

    def expressInterest(self,
                        interestOrName,
                        arg2,
                        arg3=None,
                        arg4=None,
                        arg5=None,
                        arg6=None):
        """
        Send the Interest through the transport, read the entire response and
        call onData, onTimeout or onNetworkNack as described below.
        There are two forms of expressInterest.
        The first form takes the exact interest (including lifetime):
        expressInterest(interest, onData [, onTimeout] [, onNetworkNack] [, wireFormat]).
        The second form creates the interest from a name and optional
        interest template:
        expressInterest(name [, interestTemplate], onData [, onTimeout]
        [, onNetworkNack] [, wireFormat]).

        :param Interest interest: The Interest (if the first form is used). This
          copies the Interest.
        :param Name name: A name for the Interest (if the second form is used).
        :param Interest interestTemplate: (optional) if not None, copy interest
          selectors from the template (if the second form is used).  If omitted,
          use a default interest lifetime.
        :param onData: When a matching data packet is received, this calls
          onData(interest, data) where interest is the interest given to
          expressInterest and data is the received Data object. NOTE: You must
          not change the interest object - if you need to change it then make a
          copy.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onData: function object
        :param onTimeout: (optional) If the interest times out according to the
          interest lifetime, this calls onTimeout(interest) where interest is
          the interest given to expressInterest. However, if onTimeout is None
          or omitted, this does not use it.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onTimeout: function object
        :param onNetworkNack: (optional) When a network Nack packet for the
          interest is received and onNetworkNack is not None, this calls
          onNetworkNack(interest, networkNack) and does not call onTimeout.
          interest is the sent Interest and networkNack is the received
          NetworkNack. If onNetworkNack is supplied, then onTimeout must be
          supplied too. However, if a network Nack is received and onNetworkNack
          is null, do nothing and wait for the interest to time out. (Therefore,
          an application which does not yet process a network Nack reason treats
          a Nack the same as a timeout.)
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onNetworkNack: function object
        :param wireFormat: (optional) A WireFormat object used to encode the
           message. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :return:  The pending interest ID which can be used with
          removePendingInterest.
        :rtype: int
        :throws: RuntimeError If the encoded interest size exceeds
          Face.getMaxNdnPacketSize().
        """
        args = self._getExpressInterestArgs(interestOrName, arg2, arg3, arg4,
                                            arg5, arg6)
        self._node.expressInterest(args['pendingInterestId'],
                                   args['interestCopy'], args['onData'],
                                   args['onTimeout'], args['onNetworkNack'],
                                   args['wireFormat'], self)

        return args['pendingInterestId']

    def _getExpressInterestArgs(self, interestOrName, arg2, arg3, arg4, arg5,
                                arg6):
        """
        This is a protected helper method to resolve the different overloaded
        forms of Face.expressInterest and return the arguments to pass to
        Node.expressInterest. This is necessary to prepare arguments such as
        interestCopy before dispatching to Node.expressInterest.

        :return: A dictionary with the following keys: 'pendingInterestId',
          'interestCopy', 'onData', 'onTimeout', 'onNetworkNack' and 'wireFormat'.
        :rtype: dict
        """
        if type(interestOrName) is Interest:
            # Node.expressInterest requires a copy of the interest.
            interestCopy = Interest(interestOrName)
        else:
            # The first argument is a name. Make the interest from the name and
            #   possible template.
            if type(arg2) is Interest:
                template = arg2
                # Copy the template.
                interestCopy = Interest(template)
                interestCopy.setName(interestOrName)

                # Shift the remaining args to be processed below.
                arg2 = arg3
                arg3 = arg4
                arg4 = arg5
                arg5 = arg6
            else:
                # No template.
                interestCopy = Interest(interestOrName)
                # Set a default interest lifetime.
                interestCopy.setInterestLifetimeMilliseconds(4000.0)

        onData = arg2
        # arg3,       arg4,          arg5 may be:
        # OnTimeout,  OnNetworkNack, WireFormat
        # OnTimeout,  OnNetworkNack, None
        # OnTimeout,  WireFormat,    None
        # OnTimeout,  None,          None
        # WireFormat, None,          None
        # None,       None,          None
        if isinstance(arg3, collections.Callable):
            onTimeout = arg3
        else:
            onTimeout = None

        if isinstance(arg4, collections.Callable):
            onNetworkNack = arg4
        else:
            onNetworkNack = None

        if isinstance(arg3, WireFormat):
            wireFormat = arg3
        elif isinstance(arg4, WireFormat):
            wireFormat = arg4
        elif isinstance(arg5, WireFormat):
            wireFormat = arg5
        else:
            wireFormat = WireFormat.getDefaultWireFormat()

        return {
            'pendingInterestId': self._node.getNextEntryId(),
            'interestCopy': interestCopy,
            'onData': onData,
            'onTimeout': onTimeout,
            'onNetworkNack': onNetworkNack,
            'wireFormat': wireFormat
        }

    def removePendingInterest(self, pendingInterestId):
        """
        Remove the pending interest entry with the pendingInterestId from the
        pending interest table. This does not affect another pending interest
        with a different pendingInterestId, even if it has the same interest
        name. If there is no entry with the pendingInterestId, do nothing.

        :param int pendingInterestId: The ID returned from expressInterest.
        """
        self._node.removePendingInterest(pendingInterestId)

    def setCommandSigningInfo(self, keyChain, certificateName):
        """
        Set the KeyChain and certificate name used to sign command interests
        (e.g. for registerPrefix).

        :param KeyChain keyChain: The KeyChain object for signing interests,
          which must remain valid for the life of this Face. You must create the
          KeyChain object and pass it in. You can create a default KeyChain for
          your system with the default KeyChain constructor.
        :param Name certificateName: The certificate name for signing interests.
          This makes a copy of the Name. You can get the default certificate
          name with keyChain.getDefaultCertificateName() .
        """
        self._commandKeyChain = keyChain
        self._commandCertificateName = Name(certificateName)

    def setCommandCertificateName(self, certificateName):
        """
        Set the certificate name used to sign command interest (e.g. for
        registerPrefix), using the KeyChain that was set with
        setCommandSigningInfo.

        :param Name certificateName: The certificate name for signing interest.
          This makes a copy of the Name.
        """
        self._commandCertificateName = Name(certificateName)

    def makeCommandInterest(self, interest, wireFormat=None):
        """
        Append a timestamp component and a random value component to interest's
        name. Then use the keyChain and certificateName from
        setCommandSigningInfo to sign the interest. If the interest lifetime is
        not set, this sets it.
        :note: This method is an experimental feature. See the API docs for more
        detail at
        http://named-data.net/doc/ndn-ccl-api/face.html#face-makecommandinterest-method .

        :param Interest interest: The interest whose name is appended with
          components.
        :param wireFormat: (optional) A WireFormat object used to encode the
          SignatureInfo and to encode the interest name for signing. If omitted, use
          WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()
        self._node.makeCommandInterest(interest, self._commandKeyChain,
                                       self._commandCertificateName,
                                       wireFormat)

    def registerPrefix(self,
                       prefix,
                       onInterest,
                       onRegisterFailed,
                       onRegisterSuccess=None,
                       flags=None,
                       wireFormat=None):
        """
        Register prefix with the connected NDN hub and call onInterest when a
        matching interest is received. To register a prefix with NFD, you must
        first call setCommandSigningInfo.

        :param Name prefix: The Name for the prefix to register. This copies the
          Name.
        :param onInterest: If not None, this creates an interest filter from
          prefix so that when an Interest is received which matches the filter,
          this calls
          onInterest(prefix, interest, face, interestFilterId, filter).
          NOTE: You must not change the prefix or filter objects - if you need to
          change them then make a copy. If onInterest is None, it is ignored and
          you must call setInterestFilter.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onInterest: function object
        :param onRegisterFailed: If register prefix fails for any reason, this
          calls onRegisterFailed(prefix).
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onRegisterFailed: function object
        :param onRegisterSuccess: (optional) This calls
          onRegisterSuccess(prefix, registeredPrefixId) when this receives a
          success message from the forwarder. If onRegisterSuccess is None or
          omitted, this does not use it. (The onRegisterSuccess parameter comes
          after onRegisterFailed because it can be None or omitted, unlike
          onRegisterFailed.)
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onRegisterSuccess: function object
        :param ForwardingFlags flags: (optional) The flags for finer control of
          which interests are forwardedto the application.
        :param wireFormat: (optional) A WireFormat object used to encode this
           ControlParameters. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :raises: This raises an exception if setCommandSigningInfo has not been
          called to set the KeyChain, etc. for signing the command interest.
        """
        registeredPrefixId = self._node.getNextEntryId()

        # Node.registerPrefix requires a copy of the prefix.
        self._registerPrefixHelper(registeredPrefixId, Name(prefix),
                                   onInterest, onRegisterFailed,
                                   onRegisterSuccess, flags, wireFormat)

        return registeredPrefixId

    def _registerPrefixHelper(self,
                              registeredPrefixId,
                              prefixCopy,
                              onInterest,
                              onRegisterFailed,
                              arg5=None,
                              arg6=None,
                              arg7=None):
        """
        This is a protected helper method to do the work of registerPrefix to
        resolve the different overloaded forms. The registeredPrefixId is from
        getNextEntryId(). This has no return value and can be used in a callback.
        """
        # arg5, arg6, arg7 may be:
        # OnRegisterSuccess, ForwardingFlags, WireFormat
        # OnRegisterSuccess, ForwardingFlags, None
        # OnRegisterSuccess, WireFormat,      None
        # OnRegisterSuccess, None,            None
        # ForwardingFlags,   WireFormat,      None
        # ForwardingFlags,   None,            None
        # WireFormat,        None,            None
        # None,              None,            None
        if isinstance(arg5, collections.Callable):
            onRegisterSuccess = arg5
        else:
            onRegisterSuccess = None

        if isinstance(arg5, ForwardingFlags):
            flags = arg5
        elif isinstance(arg6, ForwardingFlags):
            flags = arg6
        else:
            flags = ForwardingFlags()

        if isinstance(arg5, WireFormat):
            wireFormat = arg5
        elif isinstance(arg6, WireFormat):
            wireFormat = arg6
        elif isinstance(arg7, WireFormat):
            wireFormat = arg7
        else:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        return self._node.registerPrefix(registeredPrefixId, prefixCopy,
                                         onInterest, onRegisterFailed,
                                         onRegisterSuccess, flags, wireFormat,
                                         self._commandKeyChain,
                                         self._commandCertificateName, self)

    def removeRegisteredPrefix(self, registeredPrefixId):
        """
        Remove the registered prefix entry with the registeredPrefixId from the
        registered prefix table. This does not affect another registered prefix
        with a different registeredPrefixId, even if it has the same prefix
        name. If there is no entry with the registeredPrefixId, do nothing.

        :param int registeredPrefixId: The ID returned from registerPrefix.
        """
        self._node.removeRegisteredPrefix(registeredPrefixId)

    def setInterestFilter(self, filterOrPrefix, onInterest):
        """
        Add an entry to the local interest filter table to call the onInterest
        callback for a matching incoming Interest. This method only modifies the
        library's local callback table and does not register the prefix with the
        forwarder. It will always succeed. To register a prefix with the
        forwarder, use registerPrefix. There are two forms of setInterestFilter.
        The first form uses the exact given InterestFilter:
        setInterestFilter(filter, onInterest).
        The second form creates an InterestFilter from the given prefix Name:
        setInterestFilter(prefix, onInterest).

        :param InterestFilter filter: The InterestFilter with a prefix and
          optional regex filter used to match the name of an incoming Interest.
          This makes a copy of filter.
        :param Name prefix: The Name prefix used to match the name of an
          incoming Interest. This makes a copy of the Name.
        :param onInterest: When an Interest is received which matches the filter,
          this calls onInterest(prefix, interest, face, interestFilterId, filter).
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onInterest: function object
        :return: The interest filter ID which can be used with unsetInterestFilter.
        :rtype: int
        """
        interestFilterId = self._node.getNextEntryId()

        # If filterOrPrefix is already an InterestFilter, the InterestFilter
        # constructor will make a copy as required by Node.setInterestFilter.
        filterCopy = InterestFilter(filterOrPrefix)

        self._node.setInterestFilter(interestFilterId, filterCopy, onInterest,
                                     self)

        return interestFilterId

    def unsetInterestFilter(self, interestFilterId):
        """
        Remove the interest filter entry which has the interestFilterId from the
        interest filter table. This does not affect another interest filter with
        a different interestFilterId, even if it has the same prefix name. If
        there is no entry with the interestFilterId, do nothing.

        :param int interestFilterId: The ID returned from setInterestFilter.
        """
        self._node.unsetInterestFilter(interestFilterId)

    def putData(self, data, wireFormat=None):
        """
        The OnInterest callback calls this to put a Data packet which satisfies
        an Interest.

        :param Data data: The Data packet which satisfies the interest.
        :param WireFormat wireFormat: (optional) A WireFormat object used to
          encode the Data packet. If omitted, use
          WireFormat.getDefaultWireFormat().
        :throws: RuntimeError If the encoded Data packet size exceeds
          getMaxNdnPacketSize().
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        # We get the encoding now before calling send because it may dispatch to
        # asyncio to be called later, and the caller may modify data before then.
        encoding = data.wireEncode(wireFormat)
        if encoding.size() > self.getMaxNdnPacketSize():
            raise RuntimeError(
                "The encoded Data packet size exceeds the maximum limit getMaxNdnPacketSize()"
            )

        self.send(encoding)

    def send(self, encoding):
        """
        Send the encoded packet out through the face.

        :param encoding: The blob or array with the the encoded packet to send.
        :type encoding: Blob or an array type with int elements
        :throws: RuntimeError If the packet size exceeds getMaxNdnPacketSize().
        """
        # If encoding is a Blob, get its buf().
        encodingBuffer = encoding.buf() if isinstance(encoding,
                                                      Blob) else encoding

        self._node.send(encodingBuffer)

    def processEvents(self):
        """
        Process any packets to receive and call callbacks such as onData,
        onInterest or onTimeout. This returns immediately if there is no data to
        receive. This blocks while calling the callbacks. You should repeatedly
        call this from an event loop, with calls to sleep as needed so that the
        loop doesn't use 100% of the CPU. Since processEvents modifies the pending
        interest table, your application should make sure that it calls
        processEvents in the same thread as expressInterest (which also modifies
        the pending interest table).

        :raises: This may raise an exception for reading data or in the callback
          for processing the data.  If you call this from an main event loop,
          you may want to catch and log/disregard all exceptions.
        """
        # Just call Node's processEvents.
        self._node.processEvents()

    def isLocal(self):
        """
        Check if the face is local based on the current connection through the
        Transport; some Transport may cause network I/O (e.g. an IP host name
        lookup).

        :return: True if the face is local, false if not.
        :rtype bool:
        """
        return self._node.isLocal()

    def shutdown(self):
        """
        Shut down and disconnect this Face.
        """
        self._node.shutdown()

    @staticmethod
    def getMaxNdnPacketSize():
        """
        Get the practical limit of the size of a network-layer packet. If a packet
        is larger than this, the library or application MAY drop it.

        :return: The maximum NDN packet size.
        :rtype: int
        """
        return Common.MAX_NDN_PACKET_SIZE

    def callLater(self, delayMilliseconds, callback):
        """
        Call callback() after the given delay. Even though this is public, it is
        not part of the public API of Face.This default implementation just
        calls Node.callLater, but a subclass can override.

        :param float delayMilliseconds: The delay in milliseconds.
        :param callback: This calls callback() after the delay.
        :type callback: function object
        """
        self._node.callLater(delayMilliseconds, callback)

    @staticmethod
    def _getUnixSocketFilePathForLocalhost():
        """
        If the forwarder's Unix socket file path exists, then return the file
        path. Otherwise return an empty string.

        :return: The Unix socket file path to use, or an empty string.
        :rtype: str
        """
        filePath = "/var/run/nfd.sock"
        # Use listdir because isfile doesn't see socket file types.
        if (os.path.basename(filePath)
                in os.listdir(os.path.dirname(filePath))):
            return filePath
        else:
            filePath = "/tmp/.ndnd.sock"
            if (os.path.basename(filePath)
                    in os.listdir(os.path.dirname(filePath))):
                return filePath
            else:
                return ""
示例#8
0
文件: face.py 项目: named-data/PyNDN2
class Face(object):
    """
    Create a new Face for communication with an NDN hub.  This constructor
    has the forms Face(), Face(transport, connectionInfo) or
    Face(host, port). If the default Face() constructor is used, if the
    forwarder's Unix socket file exists then connect using UnixTransport,
    otherwise connect to "localhost" on port 6363 using TcpTransport.

    :param Transport transport: An object of a subclass of Transport used for
      communication.
    :param Transport.ConnectionInfo connectionInfo: An object of a subclass of
      Transport.ConnectionInfo to be used to connect to the transport.
    :param str host: In the Face(host, port) form of the constructor, host is
      the host of the NDN hub to connect using TcpTransport.
    :param int port: (optional) In the Face(host, port) form of the constructor,
      port is the port of the NDN hub. If omitted. use 6363.
    """
    def __init__(self, arg1 = None, arg2 = None):
        if arg1 == None or Common.typeIsString(arg1):
            filePath = ""
            if arg1 == None and arg2 == None:
                # Check if we can connect using UnixSocket.
                filePath = self._getUnixSocketFilePathForLocalhost()

            if filePath == "":
                transport = TcpTransport()
                host = arg1 if arg1 != None else "localhost"
                connectionInfo = TcpTransport.ConnectionInfo(
                  host, arg2 if type(arg2) is int else 6363)
            else:
                transport = UnixTransport()
                connectionInfo = UnixTransport.ConnectionInfo(filePath)
        else:
            transport = arg1
            connectionInfo = arg2

        self._node = Node(transport, connectionInfo)
        self._commandKeyChain = None
        self._commandCertificateName = Name()

    def setInterestLoopbackEnabled(self, interestLoopbackEnabled):
        """
        Enable or disable Interest loopback. If Interest loopback is enabled,
        then an Interest to expressInterest is also sent to each of the matching
        OnInterest callbacks that the application gave to registerPrefix or
        setInterestFilter, and a Data that the application gives to putData can
        satisfy pending Interests. This way one part of an application can do
        Interest/Data exchange with another part through the same Face. Interest
        loopback is disabled by default.

        :param bool interestLoopbackEnabled: If True, enable Interest loopback,
          otherwise disable it.
        """
        self._node.setInterestLoopbackEnabled(interestLoopbackEnabled)

    def expressInterest(
      self, interestOrName, arg2, arg3 = None, arg4 = None, arg5 = None,
      arg6 = None):
        """
        Send the Interest through the transport, read the entire response and
        call onData, onTimeout or onNetworkNack as described below.
        There are two forms of expressInterest.
        The first form takes the exact interest (including lifetime):
        expressInterest(interest, onData [, onTimeout] [, onNetworkNack] [, wireFormat]).
        The second form creates the interest from a name and optional
        interest template:
        expressInterest(name [, interestTemplate], onData [, onTimeout]
        [, onNetworkNack] [, wireFormat]).

        :param Interest interest: The Interest (if the first form is used). This
          copies the Interest.
        :param Name name: A name for the Interest (if the second form is used).
        :param Interest interestTemplate: (optional) if not None, copy interest
          selectors from the template (if the second form is used).  If omitted,
          use a default interest lifetime.
        :param onData: When a matching data packet is received, this calls
          onData(interest, data) where interest is the interest given to
          expressInterest and data is the received Data object. NOTE: You must
          not change the interest object - if you need to change it then make a
          copy.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onData: function object
        :param onTimeout: (optional) If the interest times out according to the
          interest lifetime, this calls onTimeout(interest) where interest is
          the interest given to expressInterest. However, if onTimeout is None
          or omitted, this does not use it.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onTimeout: function object
        :param onNetworkNack: (optional) When a network Nack packet for the
          interest is received and onNetworkNack is not None, this calls
          onNetworkNack(interest, networkNack) and does not call onTimeout.
          interest is the sent Interest and networkNack is the received
          NetworkNack. If onNetworkNack is supplied, then onTimeout must be
          supplied too. However, if a network Nack is received and onNetworkNack
          is None, do nothing and wait for the interest to time out. (Therefore,
          an application which does not yet process a network Nack reason treats
          a Nack the same as a timeout.)
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onNetworkNack: function object
        :param wireFormat: (optional) A WireFormat object used to encode the
           message. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :return:  The pending interest ID which can be used with
          removePendingInterest.
        :rtype: int
        :throws: RuntimeError If the encoded interest size exceeds
          Face.getMaxNdnPacketSize().
        """
        args = self._getExpressInterestArgs(
          interestOrName, arg2, arg3, arg4, arg5, arg6)
        self._node.expressInterest(
          args['pendingInterestId'], args['interestCopy'], args['onData'],
          args['onTimeout'], args['onNetworkNack'], args['wireFormat'], self)

        return args['pendingInterestId']

    def _getExpressInterestArgs(self, interestOrName, arg2, arg3, arg4, arg5, arg6):
        """
        This is a protected helper method to resolve the different overloaded
        forms of Face.expressInterest and return the arguments to pass to
        Node.expressInterest. This is necessary to prepare arguments such as
        interestCopy before dispatching to Node.expressInterest.

        :return: A dictionary with the following keys: 'pendingInterestId',
          'interestCopy', 'onData', 'onTimeout', 'onNetworkNack' and 'wireFormat'.
        :rtype: dict
        """
        if isinstance(interestOrName, Interest):
            # Node.expressInterest requires a copy of the interest.
            interestCopy = Interest(interestOrName)
        else:
            # The first argument is a name. Make the interest from the name and
            #   possible template.
            if isinstance(arg2, Interest):
                template = arg2
                # Copy the template.
                interestCopy = Interest(template)
                interestCopy.setName(interestOrName)

                # Shift the remaining args to be processed below.
                arg2 = arg3
                arg3 = arg4
                arg4 = arg5
                arg5 = arg6
            else:
                # No template.
                interestCopy = Interest(interestOrName)
                # Set a default interest lifetime.
                interestCopy.setInterestLifetimeMilliseconds(4000.0)

        onData = arg2
        # arg3,       arg4,          arg5 may be:
        # OnTimeout,  OnNetworkNack, WireFormat
        # OnTimeout,  OnNetworkNack, None
        # OnTimeout,  WireFormat,    None
        # OnTimeout,  None,          None
        # WireFormat, None,          None
        # None,       None,          None
        if isinstance(arg3, collections.Callable):
            onTimeout = arg3
        else:
            onTimeout = None

        if isinstance(arg4, collections.Callable):
            onNetworkNack = arg4
        else:
            onNetworkNack = None

        if isinstance(arg3, WireFormat):
            wireFormat = arg3
        elif isinstance(arg4, WireFormat):
            wireFormat = arg4
        elif isinstance(arg5, WireFormat):
            wireFormat = arg5
        else:
            wireFormat = WireFormat.getDefaultWireFormat()

        return { 'pendingInterestId': self._node.getNextEntryId(),
          'interestCopy': interestCopy, 'onData': onData, 'onTimeout': onTimeout,
          'onNetworkNack': onNetworkNack, 'wireFormat': wireFormat }

    def removePendingInterest(self, pendingInterestId):
        """
        Remove the pending interest entry with the pendingInterestId from the
        pending interest table. This does not affect another pending interest
        with a different pendingInterestId, even if it has the same interest
        name. If there is no entry with the pendingInterestId, do nothing.

        :param int pendingInterestId: The ID returned from expressInterest.
        """
        self._node.removePendingInterest(pendingInterestId)

    def setCommandSigningInfo(self, keyChain, certificateName):
        """
        Set the KeyChain and certificate name used to sign command interests
        (e.g. for registerPrefix).

        :param KeyChain keyChain: The KeyChain object for signing interests,
          which must remain valid for the life of this Face. You must create the
          KeyChain object and pass it in. You can create a default KeyChain for
          your system with the default KeyChain constructor.
        :param Name certificateName: The certificate name for signing interests.
          This makes a copy of the Name. You can get the default certificate
          name with keyChain.getDefaultCertificateName() .
        """
        self._commandKeyChain = keyChain
        self._commandCertificateName = Name(certificateName)

    def setCommandCertificateName(self, certificateName):
        """
        Set the certificate name used to sign command interest (e.g. for
        registerPrefix), using the KeyChain that was set with
        setCommandSigningInfo.

        :param Name certificateName: The certificate name for signing interest.
          This makes a copy of the Name.
        """
        self._commandCertificateName = Name(certificateName)

    def makeCommandInterest(self, interest, wireFormat = None):
        """
        Append a timestamp component and a random value component to interest's
        name. Then use the keyChain and certificateName from
        setCommandSigningInfo to sign the interest. If the interest lifetime is
        not set, this sets it.
        :note: This method is an experimental feature. See the API docs for more
        detail at
        http://named-data.net/doc/ndn-ccl-api/face.html#face-makecommandinterest-method .

        :param Interest interest: The interest whose name is appended with
          components.
        :param wireFormat: (optional) A WireFormat object used to encode the
          SignatureInfo and to encode the interest name for signing. If omitted, use
          WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()
        self._node.makeCommandInterest(
          interest, self._commandKeyChain, self._commandCertificateName,
          wireFormat)

    def registerPrefix(
      self, prefix, onInterest, onRegisterFailed, onRegisterSuccess = None,
      registrationOptions = None, wireFormat = None):
        """
        Register prefix with the connected NDN hub and call onInterest when a
        matching interest is received. To register a prefix with NFD, you must
        first call setCommandSigningInfo.

        :param Name prefix: The Name for the prefix to register. This copies the
          Name.
        :param onInterest: If not None, this creates an interest filter from
          prefix so that when an Interest is received which matches the filter,
          this calls
          onInterest(prefix, interest, face, interestFilterId, filter).
          NOTE: You must not change the prefix or filter objects - if you need to
          change them then make a copy. If onInterest is None, it is ignored and
          you must call setInterestFilter.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onInterest: function object
        :param onRegisterFailed: If register prefix fails for any reason, this
          calls onRegisterFailed(prefix).
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onRegisterFailed: function object
        :param onRegisterSuccess: (optional) This calls
          onRegisterSuccess(prefix, registeredPrefixId) when this receives a
          success message from the forwarder. If onRegisterSuccess is None or
          omitted, this does not use it. (The onRegisterSuccess parameter comes
          after onRegisterFailed because it can be None or omitted, unlike
          onRegisterFailed.)
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onRegisterSuccess: function object
        :param RegistrationOptions registrationOptions: (optional) The
          registration options for finer control of how to forward an interest
          and other options.
        :param wireFormat: (optional) A WireFormat object used to encode this
           ControlParameters. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :raises: This raises an exception if setCommandSigningInfo has not been
          called to set the KeyChain, etc. for signing the command interest.
        """
        registeredPrefixId = self._node.getNextEntryId()

        # Node.registerPrefix requires a copy of the prefix.
        self._registerPrefixHelper(
          registeredPrefixId, Name(prefix), onInterest, onRegisterFailed,
          onRegisterSuccess, registrationOptions, wireFormat)

        return registeredPrefixId

    def _registerPrefixHelper(
      self, registeredPrefixId, prefixCopy, onInterest, onRegisterFailed,
      arg5 = None, arg6 = None, arg7 = None):
        """
        This is a protected helper method to do the work of registerPrefix to
        resolve the different overloaded forms. The registeredPrefixId is from
        getNextEntryId(). This has no return value and can be used in a callback.
        """
        # arg5, arg6, arg7 may be:
        # OnRegisterSuccess,   RegistrationOptions, WireFormat
        # OnRegisterSuccess,   RegistrationOptions, None
        # OnRegisterSuccess,   WireFormat,          None
        # OnRegisterSuccess,   None,                None
        # RegistrationOptions, WireFormat,          None
        # RegistrationOptions, None,                None
        # WireFormat,          None,                None
        # None,                None,                None
        if isinstance(arg5, collections.Callable):
            onRegisterSuccess = arg5
        else:
            onRegisterSuccess = None

        if isinstance(arg5, RegistrationOptions):
            registrationOptions = arg5
        elif isinstance(arg6, RegistrationOptions):
            registrationOptions = arg6
        else:
            registrationOptions = RegistrationOptions()

        if isinstance(arg5, WireFormat):
            wireFormat = arg5
        elif isinstance(arg6, WireFormat):
            wireFormat = arg6
        elif isinstance(arg7, WireFormat):
            wireFormat = arg7
        else:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        return self._node.registerPrefix(
          registeredPrefixId, prefixCopy, onInterest, onRegisterFailed,
          onRegisterSuccess, registrationOptions, wireFormat, self._commandKeyChain,
          self._commandCertificateName, self)

    def removeRegisteredPrefix(self, registeredPrefixId):
        """
        Remove the registered prefix entry with the registeredPrefixId from the
        registered prefix table. This does not affect another registered prefix
        with a different registeredPrefixId, even if it has the same prefix
        name. If there is no entry with the registeredPrefixId, do nothing.

        :param int registeredPrefixId: The ID returned from registerPrefix.
        """
        self._node.removeRegisteredPrefix(registeredPrefixId)

    def setInterestFilter(self, filterOrPrefix, onInterest):
        """
        Add an entry to the local interest filter table to call the onInterest
        callback for a matching incoming Interest. This method only modifies the
        library's local callback table and does not register the prefix with the
        forwarder. It will always succeed. To register a prefix with the
        forwarder, use registerPrefix. There are two forms of setInterestFilter.
        The first form uses the exact given InterestFilter:
        setInterestFilter(filter, onInterest).
        The second form creates an InterestFilter from the given prefix Name:
        setInterestFilter(prefix, onInterest).

        :param InterestFilter filter: The InterestFilter with a prefix and
          optional regex filter used to match the name of an incoming Interest.
          This makes a copy of filter.
        :param Name prefix: The Name prefix used to match the name of an
          incoming Interest. This makes a copy of the Name.
        :param onInterest: When an Interest is received which matches the filter,
          this calls onInterest(prefix, interest, face, interestFilterId, filter).
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onInterest: function object
        :return: The interest filter ID which can be used with unsetInterestFilter.
        :rtype: int
        """
        interestFilterId = self._node.getNextEntryId()

        # If filterOrPrefix is already an InterestFilter, the InterestFilter
        # constructor will make a copy as required by Node.setInterestFilter.
        filterCopy = InterestFilter(filterOrPrefix)

        self._node.setInterestFilter(
          interestFilterId, filterCopy, onInterest, self)

        return interestFilterId

    def unsetInterestFilter(self, interestFilterId):
        """
        Remove the interest filter entry which has the interestFilterId from the
        interest filter table. This does not affect another interest filter with
        a different interestFilterId, even if it has the same prefix name. If
        there is no entry with the interestFilterId, do nothing.

        :param int interestFilterId: The ID returned from setInterestFilter.
        """
        self._node.unsetInterestFilter(interestFilterId)

    def putData(self, data, wireFormat = None):
        """
        The OnInterest callback calls this to put a Data packet which satisfies
        an Interest.

        :param Data data: The Data packet which satisfies the interest.
        :param WireFormat wireFormat: (optional) A WireFormat object used to
          encode the Data packet. If omitted, use
          WireFormat.getDefaultWireFormat().
        :throws: RuntimeError If the encoded Data packet size exceeds
          getMaxNdnPacketSize().
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        self._node.putData(data, wireFormat)

    def putNack(self, interest, networkNack):
        """
        The OnInterest callback can call this to put a Nack for the received
        Interest.
        :note: This method is an experimental feature, and the API may change.

        :param Interest interest: The Interest to put in the Nack packet.
        :param NetworkNack networkNack: The NetworkNack with the reason code.
          For example, NetworkNack().setReason(NetworkNack.Reason.NO_ROUTE).
        :raises RuntimeError: If the encoded Nack packet size exceeds
          getMaxNdnPacketSize().
        """
        self._node.putNack(interest, networkNack)

    def send(self, encoding):
        """
        Send the encoded packet out through the face.

        :param encoding: The blob or array with the the encoded packet to send.
        :type encoding: Blob or an array type with int elements
        :throws: RuntimeError If the packet size exceeds getMaxNdnPacketSize().
        """
        # If encoding is a Blob, get its buf().
        encodingBuffer = encoding.buf() if isinstance(encoding, Blob) else encoding

        self._node.send(encodingBuffer)

    def processEvents(self):
        """
        Process any packets to receive and call callbacks such as onData,
        onInterest or onTimeout. This returns immediately if there is no data to
        receive. This blocks while calling the callbacks. You should repeatedly
        call this from an event loop, with calls to sleep as needed so that the
        loop doesn't use 100% of the CPU. Since processEvents modifies the pending
        interest table, your application should make sure that it calls
        processEvents in the same thread as expressInterest (which also modifies
        the pending interest table).

        :raises: This may raise an exception for reading data or in the callback
          for processing the data.  If you call this from an main event loop,
          you may want to catch and log/disregard all exceptions.
        """
        # Just call Node's processEvents.
        self._node.processEvents()

    def isLocal(self):
        """
        Check if the face is local based on the current connection through the
        Transport; some Transport may cause network I/O (e.g. an IP host name
        lookup).

        :return: True if the face is local, false if not.
        :rtype bool:
        """
        return self._node.isLocal()

    def shutdown(self):
        """
        Shut down and disconnect this Face.
        """
        self._node.shutdown()

    @staticmethod
    def getMaxNdnPacketSize():
        """
        Get the practical limit of the size of a network-layer packet. If a packet
        is larger than this, the library or application MAY drop it.

        :return: The maximum NDN packet size.
        :rtype: int
        """
        return Common.MAX_NDN_PACKET_SIZE

    def callLater(self, delayMilliseconds, callback):
        """
        Call callback() after the given delay. Even though this is public, it is
        not part of the public API of Face.This default implementation just
        calls Node.callLater, but a subclass can override.

        :param float delayMilliseconds: The delay in milliseconds.
        :param callback: This calls callback() after the delay.
        :type callback: function object
        """
        self._node.callLater(delayMilliseconds, callback)

    @staticmethod
    def _getUnixSocketFilePathForLocalhost():
        """
        If the forwarder's Unix socket file path exists, then return the file
        path. Otherwise return an empty string.

        :return: The Unix socket file path to use, or an empty string.
        :rtype: str
        """
        filePath = "/var/run/nfd.sock"
        # Use listdir because isfile doesn't see socket file types.
        if  (os.path.basename(filePath) in
             os.listdir(os.path.dirname(filePath))):
            return filePath
        else:
            filePath = "/tmp/.ndnd.sock"
            if  (os.path.basename(filePath) in
                 os.listdir(os.path.dirname(filePath))):
                return filePath
            else:
                return ""
示例#9
0
class Face(object):
    """
    Create a new Face for communication with an NDN hub.  This constructor
    has the forms Face(), Face(transport, connectionInfo) or 
    Face(host, port). If the default Face() constructor is used, if the 
    forwarder's Unix socket file exists then connect using UnixTransport, 
    otherwise connect to "localhost" on port 6363 using TcpTransport.
    
    :param Transport transport: An object of a subclass of Transport used for 
      communication.
    :param Transport.ConnectionInfo connectionInfo: An object of a subclass of 
      Transport.ConnectionInfo to be used to connect to the transport.
    :param str host: In the Face(host, port) form of the constructor, host is
      the host of the NDN hub to connect using TcpTransport.
    :param int port: (optional) In the Face(host, port) form of the constructor, 
      port is the port of the NDN hub. If omitted. use 6363.
    """
    def __init__(self, arg1 = None, arg2 = None):
        if arg1 == None or Common.typeIsString(arg1):
            filePath = ""
            if arg1 == None and arg2 == None:
                # Check if we can connect using UnixSocket.
                tryFilePath = "/var/run/nfd.sock"
                # Use listdir because isfile doesn't see socket file types.
                if  (os.path.basename(tryFilePath) in 
                     os.listdir(os.path.dirname(tryFilePath))):
                    filePath = tryFilePath
                else:
                    tryFilePath = "/tmp/.ndnd.sock"
                    if  (os.path.basename(tryFilePath) in 
                         os.listdir(os.path.dirname(tryFilePath))):
                        filePath = tryFilePath
            
            if filePath == "":
                transport = TcpTransport()
                host = arg1 if arg1 != None else "localhost"
                connectionInfo = TcpTransport.ConnectionInfo(
                  host, arg2 if type(arg2) is int else 6363)
            else:
                transport = UnixTransport()
                connectionInfo = UnixTransport.ConnectionInfo(filePath)
        else:
            transport = arg1
            connectionInfo = arg2
            
        self._node = Node(transport, connectionInfo)
        self._commandKeyChain = None
        self._commandCertificateName = Name()
            
    def expressInterest(
      self, interestOrName, arg2, arg3 = None, arg4 = None, arg5 = None):
        """
        Send the Interest through the transport, read the entire response and 
        call onData(interest, data).  There are two forms of expressInterest.  
        The first form takes the exact interest (including lifetime):
        expressInterest(interest, onData [, onTimeout] [, wireFormat]).  
        The second form creates the interest from a name and optional 
        interest template:
        expressInterest(name [, interestTemplate], onData [, onTimeout] 
        [, wireFormat]).
        
        :param Interest interest: The Interest (if the first form is used). This 
          copies the Interest.
        :param Name name: A name for the Interest (if the second form is used).
        :param Interest interestTemplate: (optional) if not None, copy interest 
          selectors from the template (if the second form is used).  If omitted, 
          use a default interest lifetime.
        :param onData: When a matching data packet is received, this calls 
          onData(interest, data) where interest is the interest given to 
          expressInterest and data is the received Data object. NOTE: You must
          not change the interest object - if you need to change it then make a
          copy.
        :type onData: function object
        :param onTimeout: (optional) If the interest times out according to the 
          interest lifetime, this calls onTimeout(interest) where interest is 
          the interest given to expressInterest. However, if onTimeout is None 
          or omitted, this does not use it.
        :type onTimeout: function object
        :param wireFormat: (optional) A WireFormat object used to encode the 
           message. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :return:  The pending interest ID which can be used with 
          removePendingInterest.
        :rtype: int
        """
        # expressInterest(interest, onData)
        # expressInterest(interest, onData, wireFormat)
        # expressInterest(interest, onData, onTimeout)
        # expressInterest(interest, onData, onTimeout, wireFormat)
        if type(interestOrName) is Interest:
            # Node.expressInterest requires a copy of the interest.
            interest = Interest(interestOrName)
            onData = arg2
            if isinstance(arg3, WireFormat):
                onTimeout = None
                wireFormat = arg3
            else:
                onTimeout = arg3
                wireFormat = arg4
        else:
            # The first argument is a name. Make the interest from the name and 
            #   possible template.
            interest = Interest(interestOrName)
            
            # expressInterest(name, interestTemplate, onData) 
            # expressInterest(name, interestTemplate, onData, wireFormat) 
            # expressInterest(name, interestTemplate, onData, onTimeout) 
            # expressInterest(name, interestTemplate, onData, onTimeout, wireFormat) 
            if type(arg2) is Interest:
                template = arg2
                interest.setMinSuffixComponents(template.getMinSuffixComponents())
                interest.setMaxSuffixComponents(template.getMaxSuffixComponents())
                interest.setKeyLocator(template.getKeyLocator())
                interest.setExclude(template.getExclude())
                interest.setChildSelector(template.getChildSelector())
                interest.setMustBeFresh(template.getMustBeFresh())
                interest.setScope(template.getScope())
                interest.setInterestLifetimeMilliseconds(
                  template.getInterestLifetimeMilliseconds())
                # Don't copy the nonce.

                onData = arg3
                if isinstance(arg4, WireFormat):
                    onTimeout = None
                    wireFormat = arg4
                else:
                    onTimeout = arg4
                    wireFormat = arg5
            # expressInterest(name, onData) 
            # expressInterest(name, onData, wireFormat)
            # expressInterest(name, onData, onTimeout)
            # expressInterest(name, onData, onTimeout, wireFormat)
            else:
                # Set a default interest lifetime.
                interest.setInterestLifetimeMilliseconds(4000.0)
                onData = arg2
                if isinstance(arg3, WireFormat):
                    onTimeout = None
                    wireFormat = arg3
                else:
                    onTimeout = arg3
                    wireFormat = arg4
            
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        return self._node.expressInterest(
          interest, onData, onTimeout, wireFormat)

    def removePendingInterest(self, pendingInterestId):
        """
        Remove the pending interest entry with the pendingInterestId from the 
        pending interest table. This does not affect another pending interest 
        with a different pendingInterestId, even if it has the same interest 
        name. If there is no entry with the pendingInterestId, do nothing.
        
        :param int pendingInterestId: The ID returned from expressInterest.
        """
        self._node.removePendingInterest(pendingInterestId)
        
    def setCommandSigningInfo(self, keyChain, certificateName):
        """
        Set the KeyChain and certificate name used to sign command interests 
        (e.g. for registerPrefix).
        
        :param KeyChain keyChain: The KeyChain object for signing interests, 
          which must remain valid for the life of this Face. You must create the 
          KeyChain object and pass it in. You can create a default KeyChain for 
          your system with the default KeyChain constructor.
        :param Name certificateName: The certificate name for signing interests.
          This makes a copy of the Name. You can get the default certificate 
          name with keyChain.getDefaultCertificateName() .        
        """
        self._commandKeyChain = keyChain
        self._commandCertificateName = certificateName
        
    def setCommandCertificateName(self, certificateName):
        """
        Set the certificate name used to sign command interest (e.g. for
        registerPrefix), using the KeyChain that was set with 
        setCommandSigningInfo.
        
        :param Name certificateName: The certificate name for signing interest.
          This makes a copy of the Name.
        """
        self._commandCertificateName = certificateName
        
    def makeCommandInterest(self, interest, wireFormat = None):
        """
        Append a timestamp component and a random value component to interest's
        name. Then use the keyChain and certificateName from 
        setCommandSigningInfo to sign the interest. If the interest lifetime is 
        not set, this sets it.

        :param Interest interest: The interest whose name is append with 
          components.
        :param wireFormat: (optional) A WireFormat object used to encode the 
          SignatureInfo and to encode interest name for signing. If omitted, use 
          WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()
        self._node.makeCommandInterest(
          interest, self._commandKeyChain, self._commandCertificateName, 
          wireFormat)
        
    def registerPrefix(
      self, prefix, onInterest, onRegisterFailed, flags = None, 
      wireFormat = None):
        """
        Register prefix with the connected NDN hub and call onInterest when a 
        matching interest is received. If you have not called 
        setCommandSigningInfo, this assumes you are connecting to NDNx. If you 
        have called setCommandSigningInfo, this first sends an NFD registration 
        request, and if that times out then this sends an NDNx registration 
        request. If need to register a prefix with NFD, you must first call 
        setCommandSigningInfo.
        
        :param Name prefix: The Name for the prefix to register which is NOT 
          copied for this internal Node method. The Face registerPrefix is 
          reponsible for making a copy for Node to use..
        :param onInterest: When an interest is received which matches the name 
          prefix, this calls 
          onInterest(prefix, interest, transport, registeredPrefixId). NOTE: 
          You must not change the prefix object - if you need to change it then 
          make a copy.
        :type onInterest: function object
        :param onRegisterFailed: If register prefix fails for any reason, this 
          calls onRegisterFailed(prefix).
        :type onRegisterFailed: function object
        :param ForwardingFlags flags: The flags for finer control of which 
          interests are forwardedto the application.
        :param wireFormat: (optional) A WireFormat object used to encode this 
           ControlParameters. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :raises: This raises an exception if setCommandSigningInfo has not been 
          called to set the KeyChain, etc. for signing the command interest.
        """
        if flags == None:
            flags = ForwardingFlags()
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        # Node.expressInterest requires a copy of the prefix.
        self._node.registerPrefix(
          prefix, onInterest, onRegisterFailed, flags, wireFormat, 
          self._commandKeyChain, self._commandCertificateName)
        
    def removeRegisteredPrefix(self, registeredPrefixId):
        """
        Remove the registered prefix entry with the registeredPrefixId from the
        registered prefix table. This does not affect another registered prefix 
        with a different registeredPrefixId, even if it has the same prefix 
        name. If there is no entry with the registeredPrefixId, do nothing.
        
        :param int registeredPrefixId: The ID returned from registerPrefix.
        """
        self._node.removeRegisteredPrefix(registeredPrefixId)
        
    def processEvents(self):
        """
        Process any packets to receive and call callbacks such as onData, 
        onInterest or onTimeout. This returns immediately if there is no data to 
        receive. This blocks while calling the callbacks. You should repeatedly 
        call this from an event loop, with calls to sleep as needed so that the 
        loop doesn't use 100% of the CPU. Since processEvents modifies the pending 
        interest table, your application should make sure that it calls 
        processEvents in the same thread as expressInterest (which also modifies 
        the pending interest table).
        
        :raises: This may raise an exception for reading data or in the callback
          for processing the data.  If you call this from an main event loop, 
          you may want to catch and log/disregard all exceptions.
        """
        # Just call Node's processEvents.
        self._node.processEvents()
        
    def shutdown(self):
        """
        Shut down and disconnect this Face.
        """
        self._node.shutdown()
示例#10
0
文件: face.py 项目: cawka/PyNDN2
class Face(object):
    """
    Create a new Face for communication with an NDN hub.  This constructor
    has the forms Face(transport, connectionInfo) or
    Face(host, port)

    :param Transport transport: An object of a subclass of Transport used for
      communication.
    :param Transport.ConnectionInfo connectionInfo: An object of a subclass of
      Transport.ConnectionInfo to be used to connect to the transport.
    :param str host: In the Face(host, port) form of the constructor, host is
      the host of the NDN hub with a TcpTransport.
    :param int port: (optional) In the Face(host, port) form of the constructor,
      port is the port of the NDN hub. If omitted. use 6363.
    """
    def __init__(self, arg1, arg2 = None):
        if type(arg1) is str:
            transport = TcpTransport()
            connectionInfo = TcpTransport.ConnectionInfo(
              arg1, arg2 if type(arg2) is int else 6363)
        else:
            transport = arg1
            connectionInfo = arg2

        self._node = Node(transport, connectionInfo)

    def expressInterest(
      self, interestOrName, arg2, arg3 = None, arg4 = None, arg5 = None):
        """
        Send the Interest through the transport, read the entire response and
        call onData(interest, data).  There are two forms of expressInterest.
        The first form takes the exact interest (including lifetime):
        expressInterest(interest, onData [, onTimeout] [, wireFormat]).
        The second form creates the interest from a name and optional
        interest template:
        expressInterest(name [, interestTemplate], onData [, onTimeout]
        [, wireFormat]).

        :param Interest interest: The Interest (if the first form is used). This
          copies the Interest.
        :param Name name: A name for the Interest (if the second form is used).
        :param Interest interestTemplate: (optional) if not None, copy interest
          selectors from the template (if the second form is used).  If omitted,
          use a default interest lifetime.
        :param onData: A function object to call when a matching data packet is
          received.
        :type onData: function object
        :param onTimeout: (optional) A function object to call if the interest
          times out. If onTimeout is None or omitted, this does not use it.
        :type onTimeout: function object
        :param wireFormat: (optional) A WireFormat object used to encode the
           message. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        :return:  The pending interest ID which can be used with
          removePendingInterest.
        :rtype: int
        """
        # expressInterest(interest, onData)
        # expressInterest(interest, onData, wireFormat)
        # expressInterest(interest, onData, onTimeout)
        # expressInterest(interest, onData, onTimeout, wireFormat)
        if type(interestOrName) is Interest:
            # Node.expressInterest requires a copy of the interest.
            interest = Interest(interestOrName)
            onData = arg2
            if isinstance(arg3, WireFormat):
                onTimeout = None
                wireFormat = arg3
            else:
                onTimeout = arg3
                wireFormat = arg4
        else:
            # The first argument is a name. Make the interest from the name and
            #   possible template.
            interest = Interest(interestOrName)

            # expressInterest(name, interestTemplate, onData)
            # expressInterest(name, interestTemplate, onData, wireFormat)
            # expressInterest(name, interestTemplate, onData, onTimeout)
            # expressInterest(name, interestTemplate, onData, onTimeout, wireFormat)
            if type(arg2) is Interest:
                template = arg2
                interest.setMinSuffixComponents(template.getMinSuffixComponents())
                interest.setMaxSuffixComponents(template.getMaxSuffixComponents())
                interest.setKeyLocator(template.getKeyLocator())
                interest.setExclude(template.getExclude())
                interest.setChildSelector(template.getChildSelector())
                interest.setMustBeFresh(template.getMustBeFresh())
                interest.setScope(template.getScope())
                interest.setInterestLifetimeMilliseconds(
                  template.getInterestLifetimeMilliseconds())
                # Don't copy the nonce.

                onData = arg3
                if isinstance(arg4, WireFormat):
                    onTimeout = None
                    wireFormat = arg4
                else:
                    onTimeout = arg4
                    wireFormat = arg5
            # expressInterest(name, onData)
            # expressInterest(name, onData, wireFormat)
            # expressInterest(name, onData, onTimeout)
            # expressInterest(name, onData, onTimeout, wireFormat)
            else:
                # Set a default interest lifetime.
                interest.setInterestLifetimeMilliseconds(4000.0)
                onData = arg2
                if isinstance(arg3, WireFormat):
                    onTimeout = None
                    wireFormat = arg3
                else:
                    onTimeout = arg3
                    wireFormat = arg4

        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        return self._node.expressInterest(
          interest, onData, onTimeout, wireFormat)

    def removePendingInterest(self, pendingInterestId):
        """
        Remove the pending interest entry with the pendingInterestId from the
        pending interest table. This does not affect another pending interest
        with a different pendingInterestId, even if it has the same interest
        name. If there is no entry with the pendingInterestId, do nothing.

        :param int pendingInterestId: The ID returned from expressInterest.
        """
        self._node.removePendingInterest(pendingInterestId)

    def registerPrefix(
      self, prefix, onInterest, onRegisterFailed, flags = None,
      wireFormat = None):
        """
        Register prefix with the connected NDN hub and call onInterest when a
        matching interest is received.

        :param Name prefix: The Name for the prefix to register which is NOT
          copied for this internal Node method. The Face registerPrefix is
          reponsible for making a copy for Node to use..
        :param onInterest: A function object to call when a matching interest is
          received.
        :type onInterest: function object
        :param onRegisterFailed: A function object to call if failed to retrieve
          the connected hub's ID or failed to register the prefix.
        :type onRegisterFailed: function object
        :param ForwardingFlags flags: The flags for finer control of which
          interests are forwardedto the application.
        :param wireFormat: A WireFormat object used to encode the message.
        :type wireFormat: a subclass of WireFormat
        """
        if flags == None:
            flags = ForwardingFlags()
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        # Node.expressInterest requires a copy of the prefix.
        self._node.registerPrefix(
          prefix, onInterest, onRegisterFailed, flags, wireFormat)

    def removeRegisteredPrefix(self, registeredPrefixId):
        """
        Remove the registered prefix entry with the registeredPrefixId from the
        registered prefix table. This does not affect another registered prefix
        with a different registeredPrefixId, even if it has the same prefix
        name. If there is no entry with the registeredPrefixId, do nothing.

        :param int registeredPrefixId: The ID returned from registerPrefix.
        """
        self._node.removeRegisteredPrefix(registeredPrefixId)

    def processEvents(self):
        """
        Process any packets to receive and call callbacks such as onData,
        onInterest or onTimeout. This returns immediately if there is no data to
        receive. This blocks while calling the callbacks. You should repeatedly
        call this from an event loop, with calls to sleep as needed so that the
        loop doesn't use 100% of the CPU. Since processEvents modifies the pending
        interest table, your application should make sure that it calls
        processEvents in the same thread as expressInterest (which also modifies
        the pending interest table).

        :raises: This may raise an exception for reading data or in the callback
          for processing the data.  If you call this from an main event loop,
          you may want to catch and log/disregard all exceptions.
        """
        # Just call Node's processEvents.
        self._node.processEvents()

    def shutdown(self):
        """
        Shut down and disconnect this Face.
        """
        self._node.shutdown()