update ndncert client command line tool

Change-Id: Icf8ca4b35fe8fea41178cc91df38c3971358fda9
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 74985aa..b6233e9 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -127,7 +127,10 @@
     // if not a PROBE INFO, find an available name
     std::string availableId = "";
     const auto& parameterJson = jsonFromBlock(request.getApplicationParameters());
-    //m_config.m_probe
+    if (parameterJson.empty()) {
+      _LOG_ERROR("Empty JSON obtained from the Interest parameter.");
+      return;
+    }
 
     //std::string probeInfoStr = parameterJson.get(JSON_CLIENT_PROBE_INFO, "");
     if (m_config.m_probeHandler) {
@@ -144,8 +147,8 @@
       availableId = std::to_string(random::generateSecureWord64());
     }
     Name newIdentityName = m_config.m_caName;
-    _LOG_TRACE("Handle PROBE: generate an identity " << newIdentityName);
     newIdentityName.append(availableId);
+    _LOG_TRACE("Handle PROBE: generate an identity " << newIdentityName);
     contentJson = genProbeResponseJson(newIdentityName.toUri(), m_config.m_probe, parameterJson);
   }
 
@@ -161,9 +164,12 @@
 CaModule::onNew(const Interest& request)
 {
   // NEW Naming Convention: /<CA-prefix>/CA/NEW/[SignedInterestParameters_Digest]
-
   // get ECDH pub key and cert request
   const auto& parameterJson = jsonFromBlock(request.getApplicationParameters());
+  if (parameterJson.empty()) {
+    _LOG_ERROR("Empty JSON obtained from the Interest parameter.");
+    return;
+  }
   std::string peerKeyBase64 = parameterJson.get(JSON_CLIENT_ECDH, "");
 
   // get server's ECDH pub key
diff --git a/src/client-module.cpp b/src/client-module.cpp
index d107114..b3af7dd 100644
--- a/src/client-module.cpp
+++ b/src/client-module.cpp
@@ -304,39 +304,34 @@
   return json;
 }
 
-const JsonSection
-ClientModule::genProbeRequestJson(const ClientCaItem& ca, const std::string& probeInfo)
+std::vector<std::string>
+ClientModule::parseProbeComponents(const std::string& probe)
 {
+  std::vector<std::string> components;
   std::string delimiter = ":";
   size_t last = 0;
   size_t next = 0;
+  while ((next = probe.find(delimiter, last)) != std::string::npos) {
+    components.push_back(probe.substr(last, next - last));
+    last = next + 1;
+  }
+  components.push_back(probe.substr(last));
+  return components;
+}
 
+const JsonSection
+ClientModule::genProbeRequestJson(const ClientCaItem& ca, const std::string& probeInfo)
+{
   JsonSection root;
-
-  std::vector<std::string> fields;
-  while ((next = ca.m_probe.find(delimiter, last)) != std::string::npos) {
-    fields.push_back(ca.m_probe.substr(last, next - last));
-    last = next + 1;
-  }
-  fields.push_back(ca.m_probe.substr(last));
-
-  std::vector<std::string> arguments;
-  last = 0;
-  next = 0;
-  while ((next = probeInfo.find(delimiter, last)) != std::string::npos) {
-    arguments.push_back(probeInfo.substr(last, next - last));
-    last = next + 1;
-  }
-  arguments.push_back(probeInfo.substr(last));
+  std::vector<std::string> fields = parseProbeComponents(ca.m_probe);
+  std::vector<std::string> arguments  = parseProbeComponents(probeInfo);;
 
   if (arguments.size() != fields.size()) {
     BOOST_THROW_EXCEPTION(Error("Error in genProbeRequestJson: argument list does not match field list in the config file."));
   }
-
   for (size_t i = 0; i < fields.size(); ++i) {
       root.put(fields.at(i), arguments.at(i));
   }
-
   return root;
 }
 
diff --git a/src/client-module.hpp b/src/client-module.hpp
index 388ad85..330b3c6 100644
--- a/src/client-module.hpp
+++ b/src/client-module.hpp
@@ -119,6 +119,9 @@
   static Block
   paramFromJson(const JsonSection& json);
 
+  static std::vector<std::string>
+  parseProbeComponents(const std::string& probe);
+
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   const JsonSection
   genProbeRequestJson(const ClientCaItem& ca, const std::string& probeInfo);
diff --git a/tools/ndncert-client.cpp b/tools/ndncert-client.cpp
index ea38694..50057ae 100644
--- a/tools/ndncert-client.cpp
+++ b/tools/ndncert-client.cpp
@@ -22,6 +22,7 @@
 #include "challenge-module.hpp"
 #include <iostream>
 #include <string>
+#include <algorithm>
 #include <boost/program_options/options_description.hpp>
 #include <boost/program_options/variables_map.hpp>
 #include <boost/program_options/parsers.hpp>
@@ -42,7 +43,7 @@
 captureParams(const JsonSection& requirement)
 {
   std::list<std::string> results;
-  for (auto& item : requirement) {
+  for (const auto& item : requirement) {
     std::cerr << item.second.get<std::string>("") << std::endl;
     std::cerr << "Please provide the argument: " << item.first << " : " << std::endl;
     std::string tempParam;
@@ -58,6 +59,25 @@
   return results;
 }
 
+static std::list<std::string>
+captureParams(const std::vector<std::string>& requirement)
+{
+  std::list<std::string> results;
+  for (const auto& item : requirement) {
+    std::cerr << "Please provide the argument: " << item << " : " << std::endl;
+    std::string tempParam;
+    getline(std::cin, tempParam);
+    results.push_back(tempParam);
+  }
+  std::cerr << "Got it. This is what you've provided:" << std::endl;
+  auto it1 = results.begin();
+  auto it2 = requirement.begin();
+  for (; it1 != results.end() && it2 != requirement.end(); it1++, it2++) {
+    std::cerr << *it2 << " : " << *it1 << std::endl;
+  }
+  return results;
+}
+
 static void
 onNackCb()
 {
@@ -98,8 +118,9 @@
     std::list<std::string> capturedParams;
     do {
       capturedParams = captureParams(requirement);
-      std::cerr << "If anything is wrong, please type in OK; otherwise, type in REDO" << std::endl;
+      std::cerr << "If everything is right, please type in OK; otherwise, type in REDO" << std::endl;
       getline(std::cin, redo);
+      std::transform(redo.begin(), redo.end(), redo.begin(), ::toupper);
     } while (redo == "REDO");
     auto it1 = capturedParams.begin();
     auto it2 = requirement.begin();
@@ -144,8 +165,9 @@
     std::list<std::string> capturedParams;
     do {
       capturedParams = captureParams(requirement);
-      std::cerr << "If anything is wrong, please type in OK; otherwise, type in REDO" << std::endl;
+      std::cerr << "If everything is right, please type in OK; otherwise, type in REDO" << std::endl;
       getline(std::cin, redo);
+      std::transform(redo.begin(), redo.end(), redo.begin(), ::toupper);
     } while (redo == "REDO");
     auto it1 = capturedParams.begin();
     auto it2 = requirement.begin();
@@ -176,6 +198,7 @@
 
   std::string answer;
   getline(std::cin, answer);
+  std::transform(answer.begin(), answer.end(), answer.begin(), ::toupper);
   if (answer == "YES") {
     client.onProbeInfoResponse(reply);
     std::cerr << "You answered YES: new CA installed" << std::endl;
@@ -222,9 +245,11 @@
             << nStep++ << ": Please type in the CA INDEX that you want to apply"
             << " or type in NONE if your expected CA is not in the list\n";
 
-  std::string caIndexS;
+  std::string caIndexS, caIndexSUpper;
   getline(std::cin, caIndexS);
-  if (caIndexS == "NONE") {
+  caIndexSUpper = caIndexS;
+  std::transform(caIndexSUpper.begin(), caIndexSUpper.end(), caIndexSUpper.begin(), ::toupper);
+  if (caIndexSUpper == "NONE") {
     std::cerr << "Step " << nStep << ": Please type in the CA Name\n";
     face.expressInterest(*client.generateProbeInfoInterest(Name(caIndexS)),
                          bind(&probeInfoCb, _2),
@@ -237,9 +262,22 @@
     auto targetCaItem = caVector[caIndex];
 
     if (targetCaItem.m_probe != "") {
-      std::cerr << "Step " << nStep++ << ": Probe Requirement-" << targetCaItem.m_probe << std::endl;
+      std::cerr << "Step " << nStep++ << ": Please provide information for name assignment" << std::endl;
+      std::vector<std::string> probeFields = ClientModule::parseProbeComponents(targetCaItem.m_probe);
+      std::string redo = "";
+      std::list<std::string> capturedParams;
+      do {
+        capturedParams = captureParams(probeFields);
+        std::cerr << "If everything is right, please type in OK; otherwise, type in REDO" << std::endl;
+        getline(std::cin, redo);
+        std::transform(redo.begin(), redo.end(), redo.begin(), ::toupper);
+      } while (redo == "REDO");
       std::string probeInfo;
-      getline(std::cin, probeInfo);
+      for (const auto& item : capturedParams) {
+        probeInfo += item;
+        probeInfo += ":";
+      }
+      probeInfo = probeInfo.substr(0, probeInfo.size() - 1);
       face.expressInterest(*client.generateProbeInterest(targetCaItem, probeInfo),
                            bind(&probeCb, _2),
                            bind(&onNackCb),