Separate INFO out of PROBE phase

Change-Id: I8c0cae1018b2a09f19e529bcb925c11237e32027
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 63db04f..f982dc7 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -62,12 +62,12 @@
 CaModule::registerPrefix()
 {
   // register localhop discovery prefix
-  Name localhopProbePrefix("/localhop/CA/PROBE/INFO");
-  auto prefixId = m_face.setInterestFilter(InterestFilter(localhopProbePrefix),
-                                           bind(&CaModule::onProbe, this, _2),
+  Name localhopInfoPrefix("/localhop/CA/INFO");
+  auto prefixId = m_face.setInterestFilter(InterestFilter(localhopInfoPrefix),
+                                           bind(&CaModule::onInfo, this, _2),
                                            bind(&CaModule::onRegisterFailed, this, _2));
   m_registeredPrefixHandles.push_back(prefixId);
-  _LOG_TRACE("Prefix " << localhopProbePrefix << " got registered");
+  _LOG_TRACE("Prefix " << localhopInfoPrefix << " got registered");
 
   // register prefixes
   Name prefix = m_config.m_caName;
@@ -75,9 +75,14 @@
 
   prefixId = m_face.registerPrefix(prefix,
     [&] (const Name& name) {
+      // register INFO prefix
+      auto filterId = m_face.setInterestFilter(Name(name).append("INFO"),
+                                          bind(&CaModule::onInfo, this, _2));
+      m_interestFilterHandles.push_back(filterId);
+
       // register PROBE prefix
-      auto filterId = m_face.setInterestFilter(Name(name).append("PROBE"),
-                                               bind(&CaModule::onProbe, this, _2));
+      filterId = m_face.setInterestFilter(Name(name).append("PROBE"),
+                                          bind(&CaModule::onProbe, this, _2));
       m_interestFilterHandles.push_back(filterId);
 
       // register NEW prefix
@@ -115,43 +120,54 @@
 }
 
 void
+CaModule::onInfo(const Interest& request)
+{
+  _LOG_TRACE("Received INFO request");
+  JsonSection contentJson = genInfoResponseJson();
+  Data result;
+
+  result.setName(request.getName());
+  result.setContent(dataContentFromJson(contentJson));
+  result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
+
+  m_keyChain.sign(result, signingByIdentity(m_config.m_caName));
+  m_face.put(result);
+
+  _LOG_TRACE("Handle INFO: send out the INFO response");
+}
+
+void
 CaModule::onProbe(const Interest& request)
 {
-  // PROBE Naming Convention: /<CA-Prefix>/CA/PROBE/[ParametersSha256DigestComponent|INFO]
-  _LOG_TRACE("Receive PROBE request");
+  // PROBE Naming Convention: /<CA-Prefix>/CA/PROBE/[ParametersSha256DigestComponent]
+  _LOG_TRACE("Received PROBE request");
   JsonSection contentJson;
 
-  // process PROBE INFO requests
-  if (readString(request.getName().at(-1)) == "INFO") {
-    contentJson = genProbeResponseJson();
+  // process PROBE requests: find an available name
+  std::string availableId;
+  const auto& parameterJson = jsonFromBlock(request.getApplicationParameters());
+  if (parameterJson.empty()) {
+    _LOG_ERROR("Empty JSON obtained from the Interest parameter.");
+    return;
   }
-  else {
-    // if not a PROBE INFO, find an available name
-    std::string availableId;
-    const auto& parameterJson = jsonFromBlock(request.getApplicationParameters());
-    if (parameterJson.empty()) {
-      _LOG_ERROR("Empty JSON obtained from the Interest parameter.");
+  //std::string probeInfoStr = parameterJson.get(JSON_CLIENT_PROBE_INFO, "");
+  if (m_config.m_probeHandler) {
+    try {
+      availableId = m_config.m_probeHandler(parameterJson);
+    }
+    catch (const std::exception& e) {
+      _LOG_TRACE("Cannot find PROBE input from PROBE parameters: " << e.what());
       return;
     }
-    //std::string probeInfoStr = parameterJson.get(JSON_CLIENT_PROBE_INFO, "");
-    if (m_config.m_probeHandler) {
-      try {
-        availableId = m_config.m_probeHandler(parameterJson);
-      }
-      catch (const std::exception& e) {
-        _LOG_TRACE("Cannot find PROBE input from PROBE parameters: " << e.what());
-        return;
-      }
-    }
-    else {
-      // if there is no app-specified name lookup, use a random name id
-      availableId = std::to_string(random::generateSecureWord64());
-    }
-    Name newIdentityName = m_config.m_caName;
-    newIdentityName.append(availableId);
-    _LOG_TRACE("Handle PROBE: generate an identity " << newIdentityName);
-    contentJson = genProbeResponseJson(newIdentityName.toUri(), m_config.m_probe, parameterJson);
   }
+  else {
+    // if there is no app-specified name lookup, use a random name id
+    availableId = std::to_string(random::generateSecureWord64());
+  }
+  Name newIdentityName = m_config.m_caName;
+  newIdentityName.append(availableId);
+  _LOG_TRACE("Handle PROBE: generate an identity " << newIdentityName);
+  contentJson = genProbeResponseJson(newIdentityName.toUri(), m_config.m_probe, parameterJson);
 
   Data result;
   result.setName(request.getName());
@@ -485,7 +501,7 @@
  *   "name": "@p identifier"
  * }
  */
-const JsonSection
+JsonSection
 CaModule::genProbeResponseJson(const Name& identifier, const std::string& m_probe, const JsonSection& parameterJson)
 {
   std::vector<std::string> fields;
@@ -527,8 +543,8 @@
  *   ]
  * }
  */
-const JsonSection
-CaModule::genProbeResponseJson()
+JsonSection
+CaModule::genInfoResponseJson()
 {
   JsonSection root;
   // ca-prefix
@@ -558,7 +574,7 @@
   return root;
 }
 
-const JsonSection
+JsonSection
 CaModule::genNewResponseJson(const std::string& ecdhKey, const std::string& salt,
                              const CertificateRequest& request,
                              const std::list<std::string>& challenges)
@@ -579,7 +595,7 @@
   return root;
 }
 
-const JsonSection
+JsonSection
 CaModule::genChallengeResponseJson(const CertificateRequest& request)
 {
   JsonSection root;
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index 0b857b0..a873a27 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2017-2019, Regents of the University of California.
+ * Copyright (c) 2017-2020, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -72,6 +72,9 @@
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   void
+  onInfo(const Interest& request);
+
+  void
   onProbe(const Interest& request);
 
   void
@@ -96,19 +99,19 @@
   registerPrefix();
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  const JsonSection
+  JsonSection
   genProbeResponseJson(const Name& identifier,
                        const std::string& m_probe,
                        const JsonSection& parameterJson);
 
-  const JsonSection
-  genProbeResponseJson();
+  JsonSection
+  genInfoResponseJson();
 
-  const JsonSection
+  JsonSection
   genNewResponseJson(const std::string& ecdhKey, const std::string& salt,
                      const CertificateRequest& request, const std::list<std::string>& challenges);
 
-  const JsonSection
+  JsonSection
   genChallengeResponseJson(const CertificateRequest& request);
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
diff --git a/src/client-module.cpp b/src/client-module.cpp
index eff4e90..8e3bd17 100644
--- a/src/client-module.cpp
+++ b/src/client-module.cpp
@@ -46,12 +46,12 @@
 }
 
 shared_ptr<Interest>
-ClientModule::generateProbeInfoInterest(const Name& caName)
+ClientModule::generateInfoInterest(const Name& caName)
 {
   Name interestName = caName;
   if (readString(caName.at(-1)) != "CA")
     interestName.append("CA");
-  interestName.append("PROBE").append("INFO");
+  interestName.append("INFO");
   auto interest = make_shared<Interest>(interestName);
   interest->setMustBeFresh(true);
   interest->setCanBePrefix(false);
@@ -362,7 +362,7 @@
   return components;
 }
 
-const JsonSection
+JsonSection
 ClientModule::genProbeRequestJson(const ClientCaItem& ca, const std::string& probeInfo)
 {
   JsonSection root;
@@ -378,7 +378,7 @@
   return root;
 }
 
-const JsonSection
+JsonSection
 ClientModule::genNewRequestJson(const std::string& ecdhPub, const security::v2::Certificate& certRequest,
                                 const shared_ptr<Data>& probeToken)
 {
diff --git a/src/client-module.hpp b/src/client-module.hpp
index fb20d4b..7579ead 100644
--- a/src/client-module.hpp
+++ b/src/client-module.hpp
@@ -68,7 +68,7 @@
   }
 
   shared_ptr<Interest>
-  generateProbeInfoInterest(const Name& caName);
+  generateInfoInterest(const Name& caName);
 
   bool
   verifyProbeInfoResponse(const Data& reply);
@@ -128,10 +128,10 @@
   endSession();
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  const JsonSection
+  JsonSection
   genProbeRequestJson(const ClientCaItem& ca, const std::string& probeInfo);
 
-  const JsonSection
+  JsonSection
   genNewRequestJson(const std::string& ecdhPub, const security::v2::Certificate& certRequest,
                     const shared_ptr<Data>& probeToken = nullptr);
 
diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp
index e300288..6ea8947 100644
--- a/tests/unit-tests/ca-module.t.cpp
+++ b/tests/unit-tests/ca-module.t.cpp
@@ -50,7 +50,7 @@
 
   advanceClocks(time::milliseconds(20), 60);
   BOOST_CHECK_EQUAL(ca.m_registeredPrefixHandles.size(), 2);
-  BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 4);
+  BOOST_CHECK_EQUAL(ca.m_interestFilterHandles.size(), 5); // onInfo, onProbe, onNew, onChallenge, onDownload
 }
 
 BOOST_AUTO_TEST_CASE(HandleProbe)
@@ -85,7 +85,7 @@
   BOOST_CHECK_EQUAL(count, 1);
 }
 
-BOOST_AUTO_TEST_CASE(HandleProbeInfo)
+BOOST_AUTO_TEST_CASE(HandleInfo)
 {
   auto identity = addIdentity(Name("/ndn"));
   auto key = identity.getDefaultKey();
@@ -98,7 +98,7 @@
     });
   advanceClocks(time::milliseconds(20), 60);
 
-  Interest interest("/ndn/CA/PROBE/INFO");
+  Interest interest("/ndn/CA/INFO");
   interest.setCanBePrefix(false);
 
   int count = 0;
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index d276fb1..0154ea0 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
+/**
  * Copyright (c) 2017-2020, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
@@ -296,7 +296,7 @@
     std::cerr << "Step " << nStep << ": Please type in the CA Name\n";
     std::string expectedCAName;
     getline(std::cin, expectedCAName);
-    face.expressInterest(*client.generateProbeInfoInterest(Name(expectedCAName)),
+    face.expressInterest(*client.generateInfoInterest(Name(expectedCAName)),
                          bind(&probeInfoCb, _2), bind(&onNackCb), bind(&timeoutCb));
   }
   else {