Added support for removePendingInterest and removeRegisteredPrefix.
diff --git a/ndn-cpp/face.cpp b/ndn-cpp/face.cpp
index 342a585..febdc7b 100644
--- a/ndn-cpp/face.cpp
+++ b/ndn-cpp/face.cpp
@@ -10,17 +10,17 @@
namespace ndn {
-void
+unsigned int
Face::expressInterest(const Name& name, const Interest *interestTemplate, const OnData& onData, const OnTimeout& onTimeout)
{
if (interestTemplate)
- node_.expressInterest(Interest
+ return node_.expressInterest(Interest
(name, interestTemplate->getMinSuffixComponents(), interestTemplate->getMaxSuffixComponents(),
interestTemplate->getPublisherPublicKeyDigest(), interestTemplate->getExclude(),
interestTemplate->getChildSelector(), interestTemplate->getAnswerOriginKind(),
interestTemplate->getScope(), interestTemplate->getInterestLifetimeMilliseconds()), onData, onTimeout);
else
- node_.expressInterest(Interest(name, 4000.0), onData, onTimeout);
+ return node_.expressInterest(Interest(name, 4000.0), onData, onTimeout);
}
void
diff --git a/ndn-cpp/face.hpp b/ndn-cpp/face.hpp
index c3ced09..26161ab 100644
--- a/ndn-cpp/face.hpp
+++ b/ndn-cpp/face.hpp
@@ -45,11 +45,12 @@
* use func_lib::ref() as appropriate.
* @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
* This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
*/
- void
+ unsigned int
expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
{
- node_.expressInterest(interest, onData, onTimeout);
+ return node_.expressInterest(interest, onData, onTimeout);
}
/**
@@ -61,8 +62,9 @@
* use func_lib::ref() as appropriate.
* @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
* This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
*/
- void
+ unsigned int
expressInterest(const Name& name, const Interest *interestTemplate, const OnData& onData, const OnTimeout& onTimeout = OnTimeout());
/**
@@ -73,11 +75,24 @@
* use func_lib::ref() as appropriate.
* @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
* This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
*/
- void
+ unsigned int
expressInterest(const Name& name, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
{
- expressInterest(name, 0, onData, onTimeout);
+ return expressInterest(name, 0, onData, onTimeout);
+ }
+
+ /**
+ * 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 it if has the same interest name.
+ * If there is no entry with the pendingInterestId, do nothing.
+ * @param pendingInterestId The ID returned from expressInterest.
+ */
+ void
+ removePendingInterest(unsigned int pendingInterestId)
+ {
+ node_.removePendingInterest(pendingInterestId);
}
/**
@@ -90,13 +105,26 @@
* @param flags The flags for finer control of which interests are forward to the application. If omitted, use
* the default flags defined by the default ForwardingFlags constructor.
* @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The registered prefix ID which can be used with removeRegisteredPrefix.
*/
- void
+ unsigned int
registerPrefix
(const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags = ForwardingFlags(),
WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
{
- node_.registerPrefix(prefix, onInterest, onRegisterFailed, flags, wireFormat);
+ return node_.registerPrefix(prefix, onInterest, onRegisterFailed, flags, wireFormat);
+ }
+
+ /**
+ * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
+ * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+ * If there is no entry with the registeredPrefixId, do nothing.
+ * @param registeredPrefixId The ID returned from registerPrefix.
+ */
+ void
+ removeRegisteredPrefix(unsigned int registeredPrefixId)
+ {
+ node_.removeRegisteredPrefix(registeredPrefixId);
}
/**
diff --git a/ndn-cpp/node.cpp b/ndn-cpp/node.cpp
index 0309174..a86bdff 100644
--- a/ndn-cpp/node.cpp
+++ b/ndn-cpp/node.cpp
@@ -65,6 +65,9 @@
0x30, 0x18, 0xeb, 0x90, 0xfb, 0x17, 0xd3, 0xce, 0xb5
};
+unsigned int Node::PendingInterest::lastPendingInterestId_ = 0;
+unsigned int Node::RegisteredPrefix::lastRegisteredPrefixId_ = 0;
+
/**
* Set the KeyLocator using the full SELFREG_PUBLIC_KEY_DER, sign the data packet using SELFREG_PRIVATE_KEY_DER
* and set the signature.
@@ -120,33 +123,64 @@
{
}
-void
+unsigned int
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);
- pit_.push_back(shared_ptr<PitEntry>(new PitEntry(shared_ptr<const Interest>(new Interest(interest)), onData, onTimeout)));
+ unsigned int pendingInterestId = PendingInterest::getNextPendingInterestId();
+ pendingInterestTable_.push_back(shared_ptr<PendingInterest>(new PendingInterest
+ (pendingInterestId, shared_ptr<const Interest>(new Interest(interest)), onData, onTimeout)));
Blob encoding = interest.wireEncode();
transport_->send(*encoding);
+
+ return pendingInterestId;
}
-void
+void
+Node::removePendingInterest(unsigned int pendingInterestId)
+{
+ // Go backwards through the list so we can erase entries.
+ // Remove all entries even though pendingInterestId should be unique.
+ for (int i = (int)pendingInterestTable_.size() - 1; i >= 0; --i) {
+ if (pendingInterestTable_[i]->getPendingInterestId() == pendingInterestId)
+ pendingInterestTable_.erase(pendingInterestTable_.begin() + i);
+ }
+}
+
+unsigned int
Node::registerPrefix
(const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, WireFormat& wireFormat)
{
+ // Get the registeredPrefixId now so we can return it to the caller.
+ unsigned int registeredPrefixId = RegisteredPrefix::getNextRegisteredPrefixId();
+
if (ndndId_.size() == 0) {
// First fetch the ndndId of the connected hub.
NdndIdFetcher fetcher
(shared_ptr<NdndIdFetcher::Info>(new NdndIdFetcher::Info
- (this, prefix, onInterest, onRegisterFailed, flags, wireFormat)));
+ (this, registeredPrefixId, prefix, onInterest, onRegisterFailed, flags, wireFormat)));
// 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(make_shared<const Name>(prefix), onInterest, onRegisterFailed, flags, wireFormat);
+ registerPrefixHelper(registeredPrefixId, make_shared<const Name>(prefix), onInterest, onRegisterFailed, flags, wireFormat);
+
+ return registeredPrefixId;
+}
+
+void
+Node::removeRegisteredPrefix(unsigned int registeredPrefixId)
+{
+ // Go backwards through the list so we can erase entries.
+ // Remove all entries even though pendingInterestId should be unique.
+ for (int i = (int)registeredPrefixTable_.size() - 1; i >= 0; --i) {
+ if (registeredPrefixTable_[i]->getRegisteredPrefixId() == registeredPrefixId)
+ registeredPrefixTable_.erase(registeredPrefixTable_.begin() + i);
+ }
}
void
@@ -158,7 +192,7 @@
// TODO: If there are multiple connected hubs, the NDN ID is really stored per connected hub.
info_->node_.ndndId_ = signature->getPublisherPublicKeyDigest().getPublisherPublicKeyDigest();
info_->node_.registerPrefixHelper
- (info_->prefix_, info_->onInterest_, info_->onRegisterFailed_, info_->flags_, info_->wireFormat_);
+ (info_->registeredPrefixId_, info_->prefix_, info_->onInterest_, info_->onRegisterFailed_, info_->flags_, info_->wireFormat_);
}
else
info_->onRegisterFailed_(info_->prefix_);
@@ -172,7 +206,7 @@
void
Node::registerPrefixHelper
- (const shared_ptr<const Name>& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed,
+ (unsigned int registeredPrefixId, const shared_ptr<const Name>& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed,
const ForwardingFlags& flags, WireFormat& wireFormat)
{
// Create a ForwardingEntry.
@@ -201,7 +235,7 @@
Blob encodedInterest = interest.wireEncode();
// Save the onInterest callback and send the registration interest.
- registeredPrefixTable_.push_back(shared_ptr<PrefixEntry>(new PrefixEntry(prefix, onInterest)));
+ registeredPrefixTable_.push_back(shared_ptr<RegisteredPrefix>(new RegisteredPrefix(registeredPrefixId, prefix, onInterest)));
transport_->send(*encodedInterest);
}
@@ -213,9 +247,9 @@
// Check for PIT entry timeouts. Go backwards through the list so we can erase entries.
double nowMilliseconds = getNowMilliseconds();
- for (int i = (int)pit_.size() - 1; i >= 0; --i) {
- if (pit_[i]->checkTimeout(this, nowMilliseconds)) {
- pit_.erase(pit_.begin() + i);
+ for (int i = (int)pendingInterestTable_.size() - 1; i >= 0; --i) {
+ if (pendingInterestTable_[i]->checkTimeout(this, nowMilliseconds)) {
+ pendingInterestTable_.erase(pendingInterestTable_.begin() + i);
// Refresh now since the timeout callback might have delayed.
nowMilliseconds = getNowMilliseconds();
@@ -232,7 +266,7 @@
shared_ptr<Interest> interest(new Interest());
interest->wireDecode(element, elementLength);
- PrefixEntry *entry = getEntryForRegisteredPrefix(interest->getName());
+ RegisteredPrefix *entry = getEntryForRegisteredPrefix(interest->getName());
if (entry)
entry->getOnInterest()(entry->getPrefix(), interest, *transport_);
}
@@ -243,9 +277,9 @@
int iPitEntry = getEntryIndexForExpressedInterest(data->getName());
if (iPitEntry >= 0) {
// Copy pointers to the needed objects and remove the PIT entry before the calling the callback.
- const OnData onData = pit_[iPitEntry]->getOnData();
- const shared_ptr<const Interest> interest = pit_[iPitEntry]->getInterest();
- pit_.erase(pit_.begin() + iPitEntry);
+ const OnData onData = pendingInterestTable_[iPitEntry]->getOnData();
+ const shared_ptr<const Interest> interest = pendingInterestTable_[iPitEntry]->getInterest();
+ pendingInterestTable_.erase(pendingInterestTable_.begin() + iPitEntry);
onData(interest, data);
}
}
@@ -269,10 +303,11 @@
int iResult = -1;
- for (size_t i = 0; i < pit_.size(); ++i) {
- if (ndn_Interest_matchesName((struct ndn_Interest *)&pit_[i]->getInterestStruct(), &nameStruct)) {
+ for (size_t i = 0; i < pendingInterestTable_.size(); ++i) {
+ if (ndn_Interest_matchesName((struct ndn_Interest *)&pendingInterestTable_[i]->getInterestStruct(), &nameStruct)) {
if (iResult < 0 ||
- pit_[i]->getInterestStruct().name.nComponents > pit_[iResult]->getInterestStruct().name.nComponents)
+ pendingInterestTable_[i]->getInterestStruct().name.nComponents >
+ pendingInterestTable_[iResult]->getInterestStruct().name.nComponents)
// Update to the longer match.
iResult = i;
}
@@ -281,7 +316,7 @@
return iResult;
}
-Node::PrefixEntry*
+Node::RegisteredPrefix*
Node::getEntryForRegisteredPrefix(const Name& name)
{
int iResult = -1;
@@ -301,8 +336,9 @@
return 0;
}
-Node::PitEntry::PitEntry(const shared_ptr<const Interest>& interest, const OnData& onData, const OnTimeout& onTimeout)
-: interest_(interest), onData_(onData), onTimeout_(onTimeout)
+Node::PendingInterest::PendingInterest
+ (unsigned int pendingInterestId, const shared_ptr<const Interest>& interest, const OnData& onData, const OnTimeout& onTimeout)
+: pendingInterestId_(pendingInterestId), interest_(interest), onData_(onData), onTimeout_(onTimeout)
{
// Set up timeoutTime_.
if (interest_->getInterestLifetimeMilliseconds() >= 0.0)
@@ -321,7 +357,7 @@
}
bool
-Node::PitEntry::checkTimeout(Node *parent, double nowMilliseconds)
+Node::PendingInterest::checkTimeout(Node *parent, double nowMilliseconds)
{
if (timeoutTimeMilliseconds_ >= 0.0 && nowMilliseconds >= timeoutTimeMilliseconds_) {
if (onTimeout_) {
diff --git a/ndn-cpp/node.hpp b/ndn-cpp/node.hpp
index 3b79658..794120c 100644
--- a/ndn-cpp/node.hpp
+++ b/ndn-cpp/node.hpp
@@ -56,11 +56,21 @@
* use func_lib::ref() as appropriate.
* @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
* This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
*/
- void
+ unsigned int
expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout);
/**
+ * 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 it if has the same interest name.
+ * If there is no entry with the pendingInterestId, do nothing.
+ * @param pendingInterestId The ID returned from expressInterest.
+ */
+ void
+ removePendingInterest(unsigned int pendingInterestId);
+
+ /**
* 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
@@ -69,13 +79,23 @@
* This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
* @param flags The flags for finer control of which interests are forward to the application.
* @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The registered prefix ID which can be used with removeRegisteredPrefix.
*/
- void
+ unsigned int
registerPrefix
(const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags,
WireFormat& wireFormat);
/**
+ * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
+ * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+ * If there is no entry with the registeredPrefixId, do nothing.
+ * @param registeredPrefixId The ID returned from registerPrefix.
+ */
+ void
+ removeRegisteredPrefix(unsigned int registeredPrefixId);
+
+ /**
* 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.
@@ -98,15 +118,33 @@
shutdown();
private:
- class PitEntry {
+ class PendingInterest {
public:
/**
* Create a new PitEntry and set the timeoutTime_ based on the current time and the interest lifetime.
+ * @param pendingInterestId A unique ID for this entry, which you should get with getNextPendingInteresId().
* @param interest A shared_ptr for the interest.
* @param onData A function object to call when a matching data packet is received.
* @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
*/
- PitEntry(const ptr_lib::shared_ptr<const Interest>& interest, const OnData& onData, const OnTimeout& onTimeout);
+ PendingInterest
+ (unsigned int pendingInterestId, const ptr_lib::shared_ptr<const Interest>& interest, const OnData& onData,
+ const OnTimeout& onTimeout);
+
+ /**
+ * Return the next unique pending interest ID.
+ */
+ static unsigned int
+ getNextPendingInterestId()
+ {
+ return ++lastPendingInterestId_;
+ }
+
+ /**
+ * Return the pendingInterestId given to the constructor.
+ */
+ unsigned int
+ getPendingInterestId() { return pendingInterestId_; }
const ptr_lib::shared_ptr<const Interest>&
getInterest() { return interest_; }
@@ -143,23 +181,41 @@
std::vector<struct ndn_ExcludeEntry> excludeEntries_;
struct ndn_Interest interestStruct_;
+ static unsigned int lastPendingInterestId_; /**< A class variable used to get the next unique ID. */
+ unsigned int pendingInterestId_; /**< A unique identifier for this entry so it can be deleted */
const OnData onData_;
const OnTimeout onTimeout_;
double timeoutTimeMilliseconds_; /**< The time when the interest times out in milliseconds according to gettimeofday, or -1 for no timeout. */
};
- class PrefixEntry {
+ class RegisteredPrefix {
public:
/**
* Create a new PrefixEntry.
+ * @param registeredPrefixId A unique ID for this entry, which you should get with getNextRegisteredPrefixId().
* @param prefix A shared_ptr for the prefix.
* @param onInterest A function object to call when a matching data packet is received.
*/
- PrefixEntry(const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest)
- : prefix_(prefix), onInterest_(onInterest)
+ RegisteredPrefix(unsigned int registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest)
+ : registeredPrefixId_(registeredPrefixId), prefix_(prefix), onInterest_(onInterest)
{
}
+ /**
+ * Return the next unique entry ID.
+ */
+ static unsigned int
+ getNextRegisteredPrefixId()
+ {
+ return ++lastRegisteredPrefixId_;
+ }
+
+ /**
+ * Return the registeredPrefixId given to the constructor.
+ */
+ unsigned int
+ getRegisteredPrefixId() { return registeredPrefixId_; }
+
const ptr_lib::shared_ptr<const Name>&
getPrefix() { return prefix_; }
@@ -167,6 +223,8 @@
getOnInterest() { return onInterest_; }
private:
+ static unsigned int lastRegisteredPrefixId_; /**< A class variable used to get the next unique ID. */
+ unsigned int registeredPrefixId_; /**< A unique identifier for this entry so it can be deleted */
ptr_lib::shared_ptr<const Name> prefix_;
const OnInterest onInterest_;
};
@@ -200,14 +258,25 @@
class Info {
public:
- Info(Node *node, const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed,
- const ForwardingFlags& flags, WireFormat& wireFormat)
- : node_(*node), prefix_(new Name(prefix)), onInterest_(onInterest), onRegisterFailed_(onRegisterFailed),
+ /**
+ *
+ * @param node
+ * @param registeredPrefixId The PrefixEntry::getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller.
+ * @param prefix
+ * @param onInterest
+ * @param onRegisterFailed
+ * @param flags
+ * @param wireFormat
+ */
+ Info(Node *node, unsigned int registeredPrefixId, const Name& prefix, const OnInterest& onInterest,
+ const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, WireFormat& wireFormat)
+ : node_(*node), registeredPrefixId_(registeredPrefixId), prefix_(new Name(prefix)), onInterest_(onInterest), onRegisterFailed_(onRegisterFailed),
flags_(flags), wireFormat_(wireFormat)
{
}
Node& node_;
+ unsigned int registeredPrefixId_;
ptr_lib::shared_ptr<const Name> prefix_;
const OnInterest onInterest_;
const OnRegisterFailed onRegisterFailed_;
@@ -233,11 +302,12 @@
* @param name The name to find the PrefixEntry for (from the incoming interest packet).
* @return A pointer to the entry, or 0 if not found.
*/
- PrefixEntry*
+ RegisteredPrefix*
getEntryForRegisteredPrefix(const Name& name);
/**
* Do the work of registerPrefix once we know we are connected with an ndndId_.
+ * @param registeredPrefixId The PrefixEntry::getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller.
* @param prefix
* @param onInterest
* @param onRegisterFailed
@@ -246,13 +316,13 @@
*/
void
registerPrefixHelper
- (const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed,
- const ForwardingFlags& flags, WireFormat& wireFormat);
+ (unsigned int registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest,
+ const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, WireFormat& wireFormat);
ptr_lib::shared_ptr<Transport> transport_;
ptr_lib::shared_ptr<const Transport::ConnectionInfo> connectionInfo_;
- std::vector<ptr_lib::shared_ptr<PitEntry> > pit_;
- std::vector<ptr_lib::shared_ptr<PrefixEntry> > registeredPrefixTable_;
+ std::vector<ptr_lib::shared_ptr<PendingInterest> > pendingInterestTable_;
+ std::vector<ptr_lib::shared_ptr<RegisteredPrefix> > registeredPrefixTable_;
Interest ndndIdFetcherInterest_;
Blob ndndId_;
};