TLV encoding to replace JSON format message
diff --git a/src/challenge-module/challenge-credential.cpp b/src/challenge-module/challenge-credential.cpp
index 69a6bbe..a4ca557 100644
--- a/src/challenge-module/challenge-credential.cpp
+++ b/src/challenge-module/challenge-credential.cpp
@@ -78,13 +78,14 @@
 
 // For CA
 void
-ChallengeCredential::handleChallengeRequest(const JsonSection& params, CertificateRequest& request)
+ChallengeCredential::handleChallengeRequest(const Block& params, CertificateRequest& request)
 {
   if (m_trustAnchors.empty()) {
     parseConfigFile();
   }
   // load credential parameter
-  std::istringstream ss1(params.get(JSON_CREDENTIAL_CERT, ""));
+  // TODO: instead of string, should pass certificate byte value directly
+  std::istringstream ss1(readString(params.elements().at(1)));
   auto cert = io::load<security::v2::Certificate>(ss1);
   if (cert == nullptr) {
     _LOG_ERROR("Cannot load credential parameter: cert");
@@ -95,8 +96,9 @@
   }
   ss1.str("");
   ss1.clear();
+
   // load self-signed data
-  std::istringstream ss2(params.get(JSON_CREDENTIAL_SELF, ""));
+  std::istringstream ss2(readString(params.elements().at(3)));
   auto self = io::load<Data>(ss2);
   if (self == nullptr) {
     _LOG_TRACE("Cannot load credential parameter: self-signed cert");
@@ -158,5 +160,24 @@
   return result;
 }
 
+Block
+ChallengeCredential::genChallengeRequestTLV(int status, const std::string& challengeStatus, const JsonSection& params)
+{
+  Block request = makeEmptyBlock(tlv_encrypted_payload);
+  if (status == STATUS_BEFORE_CHALLENGE && challengeStatus == "") {
+    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
+    request.push_back(makeStringBlock(tlv_parameter_key, JSON_CREDENTIAL_CERT));
+    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CREDENTIAL_CERT,"")));
+    request.push_back(makeStringBlock(tlv_parameter_key, JSON_CREDENTIAL_SELF));
+    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CREDENTIAL_SELF,"")));
+  }
+  else {
+    _LOG_ERROR("Client's status and challenge status are wrong");
+  }
+  request.parse();
+  return request;
+}
+
+
 } // namespace ndncert
 } // namespace ndn
diff --git a/src/challenge-module/challenge-credential.hpp b/src/challenge-module/challenge-credential.hpp
index 5d4a93c..bf53175 100644
--- a/src/challenge-module/challenge-credential.hpp
+++ b/src/challenge-module/challenge-credential.hpp
@@ -53,7 +53,7 @@
 
   // For CA
   void
-  handleChallengeRequest(const JsonSection& params, CertificateRequest& request) override;
+  handleChallengeRequest(const Block& params, CertificateRequest& request) override;
 
   // For Client
   JsonSection
@@ -62,6 +62,9 @@
   JsonSection
   genChallengeRequestJson(int status, const std::string& challengeStatus, const JsonSection& params) override;
 
+  Block
+  genChallengeRequestTLV(int status, const std::string& challengeStatus, const JsonSection& params) override;
+
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   void
   parseConfigFile();
diff --git a/src/challenge-module/challenge-email.cpp b/src/challenge-module/challenge-email.cpp
index b9ca344..db069c8 100644
--- a/src/challenge-module/challenge-email.cpp
+++ b/src/challenge-module/challenge-email.cpp
@@ -48,12 +48,12 @@
 
 // For CA
 void
-ChallengeEmail::handleChallengeRequest(const JsonSection& params, CertificateRequest& request)
+ChallengeEmail::handleChallengeRequest(const Block& params, CertificateRequest& request)
 {
   auto currentTime = time::system_clock::now();
   if (request.m_challengeStatus == "") {
     // for the first time, init the challenge
-    std::string emailAddress = params.get(JSON_EMAIL, "");
+    std::string emailAddress = readString(params.get(tlv_parameter_value));
     if (!isValidEmailAddress(emailAddress)) {
       request.m_status = STATUS_FAILURE;
       request.m_challengeStatus = FAILURE_INVALID_EMAIL;
@@ -91,7 +91,7 @@
   else if (request.m_challengeStatus == NEED_CODE || request.m_challengeStatus == WRONG_CODE) {
     _LOG_TRACE("Challenge Interest arrives. Challenge Status: " << request.m_challengeStatus);
     // the incoming interest should bring the pin code
-    std::string givenCode = params.get(JSON_CODE, "");
+    std::string givenCode = readString(params.get(tlv_parameter_value));
     const auto realCode = request.m_challengeSecrets.get<std::string>(JSON_CODE);
     if (currentTime - time::fromIsoString(request.m_challengeTp) >= m_secretLifetime) {
       // secret expires
@@ -178,6 +178,32 @@
   return result;
 }
 
+Block
+ChallengeEmail::genChallengeRequestTLV(int status, const std::string& challengeStatus, const JsonSection& params)
+{
+  Block request = makeEmptyBlock(tlv_encrypted_payload);
+  if (status == STATUS_BEFORE_CHALLENGE && challengeStatus == "") {
+    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
+    request.push_back(makeStringBlock(tlv_parameter_key, JSON_EMAIL));
+    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_EMAIL,"")));
+  }
+  else if (status == STATUS_CHALLENGE && challengeStatus == NEED_CODE) {
+    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
+    request.push_back(makeStringBlock(tlv_parameter_key, JSON_CODE));
+    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CODE,"")));
+  }
+  else if (status == STATUS_CHALLENGE && challengeStatus == WRONG_CODE) {
+    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
+    request.push_back(makeStringBlock(tlv_parameter_key, JSON_CODE));
+    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CODE,"")));
+  }
+  else {
+    _LOG_ERROR("Client's status and challenge status are wrong");
+  }
+  request.parse();
+  return request;
+}
+
 bool
 ChallengeEmail::isValidEmailAddress(const std::string& emailAddress)
 {
diff --git a/src/challenge-module/challenge-email.hpp b/src/challenge-module/challenge-email.hpp
index 2f40f1f..4421bd3 100644
--- a/src/challenge-module/challenge-email.hpp
+++ b/src/challenge-module/challenge-email.hpp
@@ -23,6 +23,7 @@
 
 #include "../challenge-module.hpp"
 #include <ndn-cxx/util/time.hpp>
+#include <ndn-cxx/encoding/block.hpp>
 
 namespace ndn {
 namespace ndncert {
@@ -58,7 +59,7 @@
 
   // For CA
   void
-  handleChallengeRequest(const JsonSection& params, CertificateRequest& request) override;
+  handleChallengeRequest(const Block& params, CertificateRequest& request) override;
 
   // For Client
   JsonSection
@@ -67,6 +68,9 @@
   JsonSection
   genChallengeRequestJson(int status, const std::string& challengeStatus, const JsonSection& params) override;
 
+  Block
+  genChallengeRequestTLV(int status, const std::string& challengeStatus, const JsonSection& params) override;
+
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   static bool
   isValidEmailAddress(const std::string& emailAddress);
diff --git a/src/challenge-module/challenge-pin.cpp b/src/challenge-module/challenge-pin.cpp
index 87f36cc..f31ca77 100644
--- a/src/challenge-module/challenge-pin.cpp
+++ b/src/challenge-module/challenge-pin.cpp
@@ -42,7 +42,7 @@
 
 // For CA
 void
-ChallengePin::handleChallengeRequest(const JsonSection& params, CertificateRequest& request)
+ChallengePin::handleChallengeRequest(const Block& params, CertificateRequest& request)
 {
   auto currentTime = time::system_clock::now();
   if (request.m_challengeStatus == "") {
@@ -64,7 +64,7 @@
   else if (request.m_challengeStatus == NEED_CODE || request.m_challengeStatus == WRONG_CODE) {
     _LOG_TRACE("Challenge Interest arrives. Challenge Status: " << request.m_challengeStatus);
     // the incoming interest should bring the pin code
-    std::string givenCode = params.get(JSON_PIN_CODE, "");
+    std::string givenCode = readString(params.get(tlv_parameter_value));
     const auto realCode = request.m_challengeSecrets.get<std::string>(JSON_PIN_CODE);
     if (currentTime - time::fromIsoString(request.m_challengeTp) >= m_secretLifetime) {
       // secret expires
@@ -151,5 +151,29 @@
   return result;
 }
 
+Block
+ChallengePin::genChallengeRequestTLV(int status, const std::string& challengeStatus, const JsonSection& params)
+{
+  Block request = makeEmptyBlock(tlv_encrypted_payload);
+  if (status == STATUS_BEFORE_CHALLENGE && challengeStatus == "") {
+    // do nothing
+    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
+  }
+  else if (status == STATUS_CHALLENGE && challengeStatus == NEED_CODE) {
+    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
+    request.push_back(makeStringBlock(tlv_parameter_key, JSON_PIN_CODE));
+    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_PIN_CODE,"")));
+  }
+  else if (status == STATUS_CHALLENGE && challengeStatus == WRONG_CODE) {
+    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
+    request.push_back(makeStringBlock(tlv_parameter_key, JSON_PIN_CODE));
+    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_PIN_CODE,"")));
+  }
+  else {
+    _LOG_ERROR("Client's status and challenge status are wrong");
+  }
+  request.parse();
+  return request;
+}
 } // namespace ndncert
 } // namespace ndn
diff --git a/src/challenge-module/challenge-pin.hpp b/src/challenge-module/challenge-pin.hpp
index 8eef944..7ae1d75 100644
--- a/src/challenge-module/challenge-pin.hpp
+++ b/src/challenge-module/challenge-pin.hpp
@@ -53,7 +53,7 @@
 
   // For CA
   void
-  handleChallengeRequest(const JsonSection& params, CertificateRequest& request) override;
+  handleChallengeRequest(const Block& params, CertificateRequest& request) override;
 
   // For Client
   JsonSection
@@ -62,6 +62,10 @@
   JsonSection
   genChallengeRequestJson(int status, const std::string& challengeStatus, const JsonSection& params) override;
 
+  Block
+  genChallengeRequestTLV(int status, const std::string& challengeStatus, const JsonSection& params) override;
+
+
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   // challenge status
   static const std::string NEED_CODE;