Added preliminary code for registerPrefix.
diff --git a/ndn-cpp/face.hpp b/ndn-cpp/face.hpp
index 2b1a41a..0b7aa54 100644
--- a/ndn-cpp/face.hpp
+++ b/ndn-cpp/face.hpp
@@ -26,7 +26,7 @@
}
/**
- * Create a new Face for communication with an NDN hub at host:port using the default UdpTransport.
+ * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
* @param host The host of the NDN hub.
* @param port The port of the NDN hub.
*/
@@ -36,7 +36,7 @@
}
/**
- * Create a new Face for communication with an NDN hub at host with the default port 9695 and using the default UdpTransport.
+ * Create a new Face for communication with an NDN hub at host with the default port 9695 and using the default TcpTransport.
* @param host The host of the NDN hub.
*/
Face(const char *host)
@@ -122,6 +122,29 @@
}
/**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param flags The flags for finer control of which interests are forward to the application.
+ */
+ void registerPrefix(const Name &prefix, const OnInterest &onInterest, int flags)
+ {
+ node_.registerPrefix(prefix, onInterest, flags);
+ }
+
+ /**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ */
+ void registerPrefix(const Name &prefix, const OnInterest &onInterest)
+ {
+ node_.registerPrefix(prefix, onInterest);
+ }
+
+ /**
* Process any data to receive or call timeout callbacks.
* This is non-blocking and will return immediately if there is no data to receive.
* 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.
diff --git a/ndn-cpp/node.cpp b/ndn-cpp/node.cpp
index 5bee365..1461dbf 100644
--- a/ndn-cpp/node.cpp
+++ b/ndn-cpp/node.cpp
@@ -6,7 +6,6 @@
#include <sys/time.h>
#include "encoding/binary-xml-decoder.hpp"
#include "c/encoding/binary-xml.h"
-#include "data.hpp"
#include "node.hpp"
using namespace std;
@@ -21,54 +20,23 @@
gettimeofday(&t, NULL);
return t.tv_sec * 1000.0 + t.tv_usec / 1000.0;
}
-
-Node::PitEntry::PitEntry(const ptr_lib::shared_ptr<const Interest> &interest, const OnData &onData, const OnTimeout &onTimeout)
-: interest_(interest), onData_(onData), onTimeout_(onTimeout)
-{
- // Set up timeoutTime_.
- if (interest_->getInterestLifetimeMilliseconds() >= 0.0)
- timeoutTimeMilliseconds_ = getNowMilliseconds() + interest_->getInterestLifetimeMilliseconds();
- else
- // No timeout.
- timeoutTimeMilliseconds_ = -1.0;
-
- // Set up interestStruct_.
- // TODO: Doesn't this belong in the Interest class?
- nameComponents_.reserve(interest_->getName().getComponentCount());
- excludeEntries_.reserve(interest_->getExclude().getEntryCount());
- ndn_Interest_init
- (&interestStruct_, &nameComponents_[0], nameComponents_.capacity(), &excludeEntries_[0], excludeEntries_.capacity());
- interest_->get(interestStruct_);
-}
-bool Node::PitEntry::checkTimeout(Node *parent, double nowMilliseconds)
+void Node::construct()
{
- if (timeoutTimeMilliseconds_ >= 0.0 && nowMilliseconds >= timeoutTimeMilliseconds_) {
- if (onTimeout_) {
- // Ignore all exceptions.
- try {
- onTimeout_(interest_);
- }
- catch (...) { }
- }
-
- return true;
- }
- else
- return false;
+ ndndIdFetcherInterest_ = Interest(Name("/%C1.M.S.localhost/%C1.M.SRV/ndnd/KEY"), 4000.0);
}
void Node::expressInterest(const Interest &interest, const OnData &onData, const OnTimeout &onTimeout)
{
+ // TODO: Properly check if we are already connected to the expected host.
+ if (!transport_->getIsConnected())
+ transport_->connect(*connectionInfo_, *this);
+
shared_ptr<PitEntry> pitEntry(new PitEntry(shared_ptr<const Interest>(new Interest(interest)), onData, onTimeout));
pit_.push_back(pitEntry);
shared_ptr<vector<unsigned char> > encoding = pitEntry->getInterest()->wireEncode();
- // TODO: Properly check if we are already connected to the expected host.
- if (!transport_->getIsConnected())
- transport_->connect(*connectionInfo_, *this);
-
transport_->send(*encoding);
}
@@ -84,6 +52,38 @@
expressInterest(Interest(name, 4000.0), onData, onTimeout);
}
+void Node::registerPrefix(const Name &prefix, const OnInterest &onInterest, int flags)
+{
+ if (ndndId_.size() == 0) {
+ // First fetch the ndndId of the connected hub.
+ NdndIdFetcher fetcher(make_shared<NdndIdFetcher::Info>(this, prefix, onInterest, flags));
+ // It is OK for func_lib::function make a copy of the function object because the Info is in a shared_ptr.
+ expressInterest(ndndIdFetcherInterest_, fetcher, fetcher);
+ }
+ else
+ registerPrefixHelper(prefix, onInterest, flags);
+}
+
+void Node::NdndIdFetcher::operator()(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &ndndIdData)
+{
+ if (ndndIdData->getSignedInfo().getPublisherPublicKeyDigest().getPublisherPublicKeyDigest().size() > 0) {
+ // Set the ndndId_ and continue.
+ info_->node_.ndndId_ = ndndIdData->getSignedInfo().getPublisherPublicKeyDigest().getPublisherPublicKeyDigest();
+ info_->node_.registerPrefixHelper(info_->prefix_, info_->onInterest_, info_->flags_);
+ }
+ // TODO: else need to log not getting the ndndId.
+}
+
+void Node::NdndIdFetcher::operator()(const ptr_lib::shared_ptr<const Interest> &timedOutInterest)
+{
+ // TODO: Log the timeout.
+}
+
+void Node::registerPrefixHelper(const Name &prefix, const OnInterest &onInterest, int flags)
+{
+ throw logic_error("need to finish implementing registerPrefix");
+}
+
void Node::processEvents()
{
transport_->processEvents();
@@ -146,5 +146,41 @@
return iResult;
}
+
+Node::PitEntry::PitEntry(const ptr_lib::shared_ptr<const Interest> &interest, const OnData &onData, const OnTimeout &onTimeout)
+: interest_(interest), onData_(onData), onTimeout_(onTimeout)
+{
+ // Set up timeoutTime_.
+ if (interest_->getInterestLifetimeMilliseconds() >= 0.0)
+ timeoutTimeMilliseconds_ = getNowMilliseconds() + interest_->getInterestLifetimeMilliseconds();
+ else
+ // No timeout.
+ timeoutTimeMilliseconds_ = -1.0;
+
+ // Set up interestStruct_.
+ // TODO: Doesn't this belong in the Interest class?
+ nameComponents_.reserve(interest_->getName().getComponentCount());
+ excludeEntries_.reserve(interest_->getExclude().getEntryCount());
+ ndn_Interest_init
+ (&interestStruct_, &nameComponents_[0], nameComponents_.capacity(), &excludeEntries_[0], excludeEntries_.capacity());
+ interest_->get(interestStruct_);
+}
+
+bool Node::PitEntry::checkTimeout(Node *parent, double nowMilliseconds)
+{
+ if (timeoutTimeMilliseconds_ >= 0.0 && nowMilliseconds >= timeoutTimeMilliseconds_) {
+ if (onTimeout_) {
+ // Ignore all exceptions.
+ try {
+ onTimeout_(interest_);
+ }
+ catch (...) { }
+ }
+
+ return true;
+ }
+ else
+ return false;
+}
}
diff --git a/ndn-cpp/node.hpp b/ndn-cpp/node.hpp
index 277628f..54a9a16 100644
--- a/ndn-cpp/node.hpp
+++ b/ndn-cpp/node.hpp
@@ -8,7 +8,8 @@
#include "common.hpp"
#include "interest.hpp"
-#include "transport/udp-transport.hpp"
+#include "data.hpp"
+#include "transport/tcp-transport.hpp"
#include "encoding/binary-xml-element-reader.hpp"
namespace ndn {
@@ -23,6 +24,11 @@
*/
typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest> &)> OnTimeout;
+/**
+ * An OnInterest function object is used to pass a callback to registerPrefix.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Name> &, const ptr_lib::shared_ptr<const Interest> &)> OnInterest;
+
class Face;
class Node : public ElementListener {
@@ -35,25 +41,28 @@
Node(const ptr_lib::shared_ptr<Transport> &transport, const ptr_lib::shared_ptr<const Transport::ConnectionInfo> &connectionInfo)
: transport_(transport), connectionInfo_(connectionInfo)
{
+ construct();
}
/**
- * Create a new Node for communication with an NDN hub at host:port using the default UdpTransport.
+ * Create a new Node for communication with an NDN hub at host:port using the default TcpTransport.
* @param host The host of the NDN hub.
* @param port The port of the NDN hub.
*/
Node(const char *host, unsigned short port)
- : transport_(new UdpTransport()), connectionInfo_(new UdpTransport::ConnectionInfo(host, port))
+ : transport_(new TcpTransport()), connectionInfo_(new TcpTransport::ConnectionInfo(host, port))
{
+ construct();
}
/**
- * Create a new Node for communication with an NDN hub at host with the default port 9695 and using the default UdpTransport.
+ * Create a new Node for communication with an NDN hub at host with the default port 9695 and using the default TcpTransport.
* @param host The host of the NDN hub.
*/
Node(const char *host)
- : transport_(new UdpTransport()), connectionInfo_(new UdpTransport::ConnectionInfo(host, 9695))
+ : transport_(new TcpTransport()), connectionInfo_(new TcpTransport::ConnectionInfo(host, 9695))
{
+ construct();
}
/**
@@ -128,6 +137,26 @@
}
/**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param flags The flags for finer control of which interests are forward to the application.
+ */
+ void registerPrefix(const Name &prefix, const OnInterest &onInterest, int flags);
+
+ /**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ */
+ void registerPrefix(const Name &prefix, const OnInterest &onInterest)
+ {
+ registerPrefix(prefix, onInterest, 0);
+ }
+
+ /**
* Process any data to receive. For each element received, call onReceivedElement.
* This is non-blocking and will return immediately if there is no data to receive.
* 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.
@@ -194,6 +223,53 @@
};
/**
+ * An NdndIdFetcher receives the Data packet with the publisher public key digest for the connected NDN hub.
+ * This class is a function object for the callbacks. It only holds a pointer to an Info object, so it is OK to copy the pointer.
+ */
+ class NdndIdFetcher {
+ public:
+ class Info;
+ NdndIdFetcher(ptr_lib::shared_ptr<NdndIdFetcher::Info> info)
+ : info_(info)
+ {
+ }
+
+ /**
+ * We received the ndnd ID.
+ * @param interest
+ * @param data
+ */
+ void operator()(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &ndndIdData);
+
+ /**
+ * We timed out fetching the ndnd ID.
+ * @param interest
+ */
+ void operator()(const ptr_lib::shared_ptr<const Interest> &timedOutInterest);
+
+ class Info {
+ public:
+ Info(Node *node, const Name &prefix, const OnInterest &onInterest, int flags)
+ : node_(*node), prefix_(prefix), onInterest_(onInterest), flags_(flags)
+ {
+ }
+
+ Node &node_;
+ Name prefix_;
+ const OnInterest onInterest_;
+ int flags_;
+ };
+
+ private:
+ ptr_lib::shared_ptr<Info> info_;
+ };
+
+ /**
+ * Finish constructing this object.
+ */
+ void construct();
+
+ /**
* Find the entry from the pit_ where the name conforms to the entry's interest selectors, and
* the entry interest name is the longest that matches name.
* @param name The name to find the interest for (from the incoming data packet).
@@ -201,9 +277,19 @@
*/
int getEntryIndexForExpressedInterest(const Name &name);
+ /**
+ * Do the work of registerPrefix once we know we are connected with an ndndId_.
+ * @param prefix
+ * @param onInterest
+ * @param flags
+ */
+ void registerPrefixHelper(const Name &prefix, const OnInterest &onInterest, int flags);
+
ptr_lib::shared_ptr<Transport> transport_;
ptr_lib::shared_ptr<const Transport::ConnectionInfo> connectionInfo_;
std::vector<ptr_lib::shared_ptr<PitEntry> > pit_;
+ Interest ndndIdFetcherInterest_;
+ std::vector<unsigned char> ndndId_;
};
}