putchunks: respond to RDR discovery Interests

Change-Id: Id1039246304a3069f158aecf21724568db434958
refs: #4556
diff --git a/tools/chunks/putchunks/producer.cpp b/tools/chunks/putchunks/producer.cpp
index 4483558..ff4bafb 100644
--- a/tools/chunks/putchunks/producer.cpp
+++ b/tools/chunks/putchunks/producer.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2018, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -25,10 +25,13 @@
  * @author Andrea Tosatto
  * @author Davide Pesavento
  * @author Klaus Schneider
+ * @author Chavoosh Ghasemi
  */
 
 #include "producer.hpp"
 
+#include <ndn-cxx/metadata-object.hpp>
+
 namespace ndn {
 namespace chunks {
 
@@ -52,10 +55,19 @@
   if (m_options.wantShowVersion)
     std::cout << m_versionedPrefix[-1] << std::endl;
 
-  m_face.setInterestFilter(m_prefix,
-                           bind(&Producer::onInterest, this, _2),
-                           RegisterPrefixSuccessCallback(),
-                           bind(&Producer::onRegisterFailed, this, _1, _2));
+  // register m_prefix without interest handler
+  m_face.registerPrefix(m_prefix, nullptr, bind(&Producer::onRegisterFailed, this, _1, _2));
+
+  // match Interests whose name starts with m_versionedPrefix
+  face.setInterestFilter(m_versionedPrefix, bind(&Producer::processSegmentInterest, this, _2));
+
+  // match Interests whose name is exactly m_prefix
+  face.setInterestFilter(InterestFilter(m_prefix, ""),
+                         bind(&Producer::processSegmentInterest, this, _2));
+
+  // match discovery Interests
+  face.setInterestFilter(MetadataObject::makeDiscoveryInterest(m_prefix).getName(),
+                         bind(&Producer::processDiscoveryInterest, this, _2));
 
   if (!m_options.isQuiet)
     std::cerr << "Data published with name: " << m_versionedPrefix << std::endl;
@@ -68,7 +80,32 @@
 }
 
 void
-Producer::onInterest(const Interest& interest)
+Producer::processDiscoveryInterest(const Interest& interest)
+{
+  if (m_options.isVerbose)
+    std::cerr << "Discovery Interest: " << interest << std::endl;
+
+  if (!interest.getCanBePrefix()) {
+    if (m_options.isVerbose)
+      std::cerr << "Discovery Interest lacks CanBePrefix, sending Nack" << std::endl;
+    m_face.put(lp::Nack(interest));
+    return;
+  }
+
+  MetadataObject mobject;
+  mobject.setVersionedName(m_versionedPrefix);
+
+  // make a metadata packet based on the received discovery Interest name
+  Data mdata(mobject.makeData(interest.getName(), m_keyChain, m_options.signingInfo));
+
+  if (m_options.isVerbose)
+    std::cerr << "Sending metadata: " << mdata << std::endl;
+
+  m_face.put(mdata);
+}
+
+void
+Producer::processSegmentInterest(const Interest& interest)
 {
   BOOST_ASSERT(m_store.size() > 0);
 
@@ -78,9 +115,7 @@
   const Name& name = interest.getName();
   shared_ptr<Data> data;
 
-  // is this a discovery Interest or a sequence retrieval?
-  if (name.size() == m_versionedPrefix.size() + 1 && m_versionedPrefix.isPrefixOf(name) &&
-      name[-1].isSegment()) {
+  if (name.size() == m_versionedPrefix.size() + 1 && name[-1].isSegment()) {
     const auto segmentNo = static_cast<size_t>(interest.getName()[-1].toSegment());
     // specific segment retrieval
     if (segmentNo < m_store.size()) {
@@ -88,7 +123,7 @@
     }
   }
   else if (interest.matchesData(*m_store[0])) {
-    // Interest has version and is looking for the first segment or has no version
+    // unspecified version or segment number, return first segment
     data = m_store[0];
   }
 
@@ -98,6 +133,11 @@
 
     m_face.put(*data);
   }
+  else {
+    if (m_options.isVerbose)
+      std::cerr << "Interest cannot be satisfied, sending Nack" << std::endl;
+    m_face.put(lp::Nack(interest));
+  }
 }
 
 void
diff --git a/tools/chunks/putchunks/producer.hpp b/tools/chunks/putchunks/producer.hpp
index f498ec7..722e248 100644
--- a/tools/chunks/putchunks/producer.hpp
+++ b/tools/chunks/putchunks/producer.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2017, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -85,8 +85,17 @@
   void
   populateStore(std::istream& is);
 
+  /**
+   * @brief Respond with a metadata packet containing the versioned content name
+   */
   void
-  onInterest(const Interest& interest);
+  processDiscoveryInterest(const Interest& interest);
+
+  /**
+   * @brief Respond with the requested segment of content
+   */
+  void
+  processSegmentInterest(const Interest& interest);
 
   void
   onRegisterFailed(const Name& prefix, const std::string& reason);