fix CHALLENGE state error

Change-Id: Ic555b6be9bceeebe9076847be9fd6f139943ef16
diff --git a/src/identity-challenge/challenge-module.cpp b/src/identity-challenge/challenge-module.cpp
index 0570ed5..28624d7 100644
--- a/src/identity-challenge/challenge-module.cpp
+++ b/src/identity-challenge/challenge-module.cpp
@@ -24,6 +24,8 @@
 namespace ndn {
 namespace ndncert {
 
+const std::string ChallengeModule::SUCCESS = "success";
+
 ChallengeModule::ChallengeModule(const std::string& challengeType,
                                  size_t maxAttemptTimes,
                                  time::seconds secretLifetime)
diff --git a/src/identity-challenge/challenge-module.hpp b/src/identity-challenge/challenge-module.hpp
index deed763..7021666 100644
--- a/src/identity-challenge/challenge-module.hpp
+++ b/src/identity-challenge/challenge-module.hpp
@@ -81,6 +81,8 @@
   const size_t m_maxAttemptTimes;
   const time::seconds m_secretLifetime;
 
+  static const std::string SUCCESS;
+
 private:
   typedef function<unique_ptr<ChallengeModule>()> ChallengeCreateFunc;
   typedef std::map<std::string, ChallengeCreateFunc> ChallengeFactory;
diff --git a/src/protocol-detail/challenge.cpp b/src/protocol-detail/challenge.cpp
index 0116923..bc53b8c 100644
--- a/src/protocol-detail/challenge.cpp
+++ b/src/protocol-detail/challenge.cpp
@@ -23,14 +23,22 @@
 namespace ndn {
 namespace ndncert {
 
+_LOG_INIT(ndncert.encoding.challenge);
+
 Block
 CHALLENGE::encodeDataPayload(const CaState& request)
 {
   Block response = makeEmptyBlock(tlv_encrypted_payload);
   response.push_back(makeNonNegativeIntegerBlock(tlv_status, static_cast<size_t>(request.m_status)));
-  response.push_back(makeStringBlock(tlv_challenge_status, request.m_challengeState->m_challengeStatus));
-  response.push_back(makeNonNegativeIntegerBlock(tlv_remaining_tries, request.m_challengeState->m_remainingTries));
-  response.push_back(makeNonNegativeIntegerBlock(tlv_remaining_time, request.m_challengeState->m_remainingTime.count()));
+  if (request.m_challengeState) {
+    response.push_back(makeStringBlock(tlv_challenge_status, request.m_challengeState->m_challengeStatus));
+    response.push_back(
+            makeNonNegativeIntegerBlock(tlv_remaining_tries, request.m_challengeState->m_remainingTries));
+    response.push_back(
+            makeNonNegativeIntegerBlock(tlv_remaining_time, request.m_challengeState->m_remainingTime.count()));
+  } else if (request.m_status != Status::SUCCESS || request.m_status != Status::FAILURE){
+      _LOG_ERROR("Unsuccessful challenge does not have a challenge state");
+  }
   response.encode();
   return response;
 }
@@ -39,17 +47,22 @@
 CHALLENGE::decodeDataPayload(const Block& data){
     data.parse();
     Status status = static_cast<Status>(readNonNegativeInteger(data.get(tlv_status)));
-    std::string challengeStatus = readString(data.get(tlv_challenge_status));
-    size_t remainingTries = readNonNegativeInteger(data.get(tlv_remaining_tries));
-    time::seconds remainingTime = time::seconds(readNonNegativeInteger(data.get(tlv_remaining_time)));
-
+    DecodedData decodedData{status, nullopt, nullopt, nullopt, nullopt};
+    if (data.find(tlv_challenge_status) != data.elements_end()) {
+      decodedData.challengeStatus = readString(data.get(tlv_challenge_status));
+    }
+    if (data.find(tlv_remaining_tries) != data.elements_end()) {
+      decodedData.remainingTries = readNonNegativeInteger(data.get(tlv_remaining_tries));
+    }
+    if (data.find(tlv_remaining_time) != data.elements_end()) {
+      decodedData.remainingTime = time::seconds(readNonNegativeInteger(data.get(tlv_remaining_time)));
+    }
     if (data.find(tlv_issued_cert_name) != data.elements_end()) {
-        Block issuedCertNameBlock = data.get(tlv_issued_cert_name);
-        issuedCertNameBlock.parse();
-        return DecodedData{status, challengeStatus, remainingTries, remainingTime, Name(issuedCertNameBlock.get(tlv::Name))};
+      Block issuedCertNameBlock = data.get(tlv_issued_cert_name);
+      decodedData.issuedCertName = Name(issuedCertNameBlock.blockFromValue());
     }
 
-    return DecodedData{status, challengeStatus, remainingTries, remainingTime, nullopt};
+    return decodedData;
 }
 
 } // namespace ndncert
diff --git a/src/protocol-detail/challenge.hpp b/src/protocol-detail/challenge.hpp
index e50d01e..42eb485 100644
--- a/src/protocol-detail/challenge.hpp
+++ b/src/protocol-detail/challenge.hpp
@@ -33,9 +33,9 @@
 
   struct DecodedData{
       Status status;
-      std::string challengeStatus;
-      size_t remainingTries;
-      time::seconds remainingTime;
+      optional<std::string> challengeStatus;
+      optional<size_t> remainingTries;
+      optional<time::seconds> remainingTime;
       optional<Name> issuedCertName;
   };
 
diff --git a/src/requester.cpp b/src/requester.cpp
index 2e6a517..5229c9c 100644
--- a/src/requester.cpp
+++ b/src/requester.cpp
@@ -271,9 +271,11 @@
 
   // update state
   state.m_status = decoded.status;
-  state.m_challengeStatus = decoded.challengeStatus;
-  state.m_remainingTries = decoded.remainingTries;
-  state.m_freshBefore = time::system_clock::now() + decoded.remainingTime;
+  if (decoded.status != Status::SUCCESS && decoded.status != Status::FAILURE) {
+    state.m_challengeStatus = *decoded.challengeStatus;
+    state.m_remainingTries = *decoded.remainingTries;
+    state.m_freshBefore = time::system_clock::now() + *decoded.remainingTime;
+  }
 
   if (decoded.issuedCertName) {
     state.m_issuedCertName = *decoded.issuedCertName;