add PROBE redirection to protocol detail

Change-Id: I8b38ef87e978d05792197f2be330ec1f97f60b3d
diff --git a/src/challenge-module.hpp b/src/challenge-module.hpp
index bef26b5..1219399 100644
--- a/src/challenge-module.hpp
+++ b/src/challenge-module.hpp
@@ -22,7 +22,6 @@
 #define NDNCERT_CHALLENGE_MODULE_HPP
 
 #include "request-state.hpp"
-#include <tuple>
 
 namespace ndn {
 namespace ndncert {
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 18b71a0..8d1d397 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -136,15 +136,15 @@
     for (const auto item : *redirectionItems) {
       auto caPrefixStr = item.second.get(CONFIG_CA_PREFIX, "");
       auto caCertStr = item.second.get(CONFIG_CERTIFICATE, "");
-      if (caPrefixStr == "" || caCertStr == "") {
+      if (caCertStr == "") {
         BOOST_THROW_EXCEPTION(std::runtime_error("Redirect-to item's ca-prefix or certificate cannot be empty."));
       }
       std::istringstream ss(caCertStr);
       auto caCert = io::load<security::v2::Certificate>(ss);
       if (!m_redirection) {
-        m_redirection = RedirectionItems();
+        m_redirection = std::vector<std::shared_ptr<security::v2::Certificate>>();
       }
-      m_redirection->push_back(std::make_tuple(Name(caPrefixStr), caCert));
+      m_redirection->push_back(caCert);
     }
   }
 }
diff --git a/src/configuration.hpp b/src/configuration.hpp
index e1706e7..892c056 100644
--- a/src/configuration.hpp
+++ b/src/configuration.hpp
@@ -136,8 +136,7 @@
    * Used for CA redirection as specified in
    * https://github.com/named-data/ndncert/wiki/NDNCERT-Protocol-0.3-PROBE-Extensions#probe-extension-for-redirection
    */
-  using RedirectionItems = std::vector<std::tuple<Name, std::shared_ptr<security::v2::Certificate>>>;
-  boost::optional<RedirectionItems> m_redirection;
+  boost::optional<std::vector<std::shared_ptr<security::v2::Certificate>>> m_redirection;
   /**
    * NameAssignmentFunc Callback function
    */
diff --git a/src/ndncert-common.hpp b/src/ndncert-common.hpp
index 43f59d8..c680923 100644
--- a/src/ndncert-common.hpp
+++ b/src/ndncert-common.hpp
@@ -37,6 +37,8 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <tuple>
+#include <ndn-cxx/encoding/tlv.hpp>
 #include <ndn-cxx/data.hpp>
 #include <ndn-cxx/encoding/block.hpp>
 #include <ndn-cxx/face.hpp>
@@ -106,7 +108,8 @@
   tlv_error_code = 171,
   tlv_error_info = 173,
   tlv_authentication_tag = 175,
-  tlv_cert_to_revoke = 177
+  tlv_cert_to_revoke = 177,
+  tlv_probe_redirect = 179
 };
 
 // Parse CA Configuration file
diff --git a/src/protocol-detail/probe.cpp b/src/protocol-detail/probe.cpp
index c7b72d5..d2f9e7e 100644
--- a/src/protocol-detail/probe.cpp
+++ b/src/protocol-detail/probe.cpp
@@ -20,13 +20,9 @@
 
 #include "probe.hpp"
 
-#include <boost/throw_exception.hpp>
-#include <ndn-cxx/encoding/tlv.hpp>
-
 namespace ndn {
 namespace ndncert {
 
-// For Client
 Block
 PROBE::encodeApplicationParameters(std::vector<std::tuple<std::string, std::string>>&& parameters)
 {
@@ -53,7 +49,8 @@
 }
 
 Block
-PROBE::encodeDataContent(const std::vector<Name>& identifiers, boost::optional<size_t> maxSuffixLength)
+PROBE::encodeDataContent(const std::vector<Name>& identifiers, boost::optional<size_t> maxSuffixLength,
+                         boost::optional<std::vector<std::shared_ptr<security::v2::Certificate>>> redirectionItems)
 {
   Block content = makeEmptyBlock(tlv::Content);
   for (const auto& name : identifiers) {
@@ -62,21 +59,29 @@
   if (maxSuffixLength) {
     content.push_back(makeNonNegativeIntegerBlock(tlv_max_suffix_length, *maxSuffixLength));
   }
+  if (redirectionItems) {
+    for (const auto& item : *redirectionItems) {
+      content.push_back(makeNestedBlock(tlv_probe_redirect, item->getFullName()));
+    }
+  }
   content.encode();
   return content;
 }
 
-std::vector<Name>
-PROBE::decodeDataContent(const Block& block)
+void
+PROBE::decodeDataContent(const Block& block,
+                         std::vector<Name>& availableNames,
+                         std::vector<Name>& availableRedirection)
 {
-  std::vector<Name> result;
   block.parse();
   for (const auto& item : block.elements()) {
     if (item.type() == tlv_probe_response) {
-      result.push_back(Name(item.blockFromValue()));
+      availableNames.push_back(Name(item.blockFromValue()));
+    }
+    if (item.type() == tlv_probe_redirect) {
+      availableRedirection.push_back(Name(item.blockFromValue()));
     }
   }
-  return result;
 }
 
 }  // namespace ndncert
diff --git a/src/protocol-detail/probe.hpp b/src/protocol-detail/probe.hpp
index 8d08e4b..6e19bab 100644
--- a/src/protocol-detail/probe.hpp
+++ b/src/protocol-detail/probe.hpp
@@ -28,16 +28,19 @@
 
 class PROBE {
 public:
-  // For CA use
+  // For Client use
   static Block
   encodeApplicationParameters(std::vector<std::tuple<std::string, std::string>>&& parameters);
 
-  static std::vector<Name>
-  decodeDataContent(const Block& block);
+  static void
+  decodeDataContent(const Block& block, std::vector<Name>& availableNames,
+                    std::vector<Name>& availableRedirection);
 
-  // For client use
+  // For CA use
   static Block
-  encodeDataContent(const std::vector<Name>& identifiers, boost::optional<size_t> maxSuffixLength);
+  encodeDataContent(const std::vector<Name>& identifiers,
+                    boost::optional<size_t> maxSuffixLength = boost::none,
+                    boost::optional<std::vector<std::shared_ptr<security::v2::Certificate>>> redirectionItems = boost::none);
 
   static std::vector<std::tuple<std::string, std::string>>
   decodeApplicationParameters(const Block& block);