Adding support for Timestamp and Freshness in ContentObject
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
index 4325e67..94732f7 100644
--- a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
+++ b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
@@ -20,17 +20,22 @@
 
 #include "ccnb-parser-content-object-visitor.h"
 #include "ccnb-parser-name-components-visitor.h"
+#include "ccnb-parser-non-negative-integer-visitor.h"
+#include "ccnb-parser-timestamp-visitor.h"
 
 #include "../syntax-tree/ccnb-parser-block.h"
 #include "../syntax-tree/ccnb-parser-dtag.h"
 
 #include "ns3/ccnx-name-components.h"
 #include "ns3/assert.h"
+#include "ns3/log.h"
 
 #include "ns3/ccnx-content-object-header.h"
 
 #include <boost/foreach.hpp>
 
+NS_LOG_COMPONENT_DEFINE ("CcnbParserContentObjectVisitor");
+
 namespace ns3 {
 namespace CcnbParser {
 
@@ -41,6 +46,8 @@
   // uint32_t n.m_dtag;
   // std::list<Ptr<Block> > n.m_nestedBlocks;
   static NameComponentsVisitor nameComponentsVisitor;
+  static NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
+  static TimestampVisitor          timestampVisitor;
   
   CcnxContentObjectHeader &contentObject = *(boost::any_cast<CcnxContentObjectHeader*> (param));
   
@@ -65,14 +72,51 @@
         contentObject.SetName (name);
         break;
       }
+
     case CCN_DTAG_Signature: // ignoring
       break;
-    case CCN_DTAG_SignedInfo: // ignoring
+
+    case CCN_DTAG_SignedInfo:
+      // process nested blocks
+      BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+        {
+          block->accept (*this, param);
+        }      
       break;
+      
+    case CCN_DTAG_Timestamp:
+      NS_LOG_DEBUG ("Timestamp");
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+
+      contentObject.SetTimestamp (
+               boost::any_cast<Time> (
+                                      (*n.m_nestedTags.begin())->accept(
+                                                                        timestampVisitor
+                                                                        )));
+      break;
+
+    case CCN_DTAG_FreshnessSeconds:
+      NS_LOG_DEBUG ("FreshnessSeconds");
+      
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+      contentObject.SetFreshness (
+          Seconds (
+               boost::any_cast<uint32_t> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           nonNegativeIntegerVisitor
+                                                                           ))));
+      
+      break;
+      
     case CCN_DTAG_Content: // !!! HACK
       // This hack was necessary for memory optimizations (i.e., content is virtual payload)
       NS_ASSERT_MSG (n.m_nestedTags.size() == 0, "Parser should have stopped just after processing <Content> tag");
       break;
+      
+    default: // ignore all other stuff
+      break;
     }
 }
 
diff --git a/helper/ccnx-encoding-helper.cc b/helper/ccnx-encoding-helper.cc
index e63c67c..538524c 100644
--- a/helper/ccnx-encoding-helper.cc
+++ b/helper/ccnx-encoding-helper.cc
@@ -194,6 +194,19 @@
   //                FreshnessSeconds?
   //                FinalBlockID?
   //                KeyLocator?
+  if (!contentObject.GetTimestamp ().IsZero())
+    {
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Timestamp, CcnbParser::CCN_DTAG);
+      written += AppendTimestampBlob (start, contentObject.GetTimestamp ());
+      written += AppendCloser (start);
+    }
+  if (contentObject.GetFreshness () >= Seconds(0))
+    {
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_FreshnessSeconds, CcnbParser::CCN_DTAG);
+      written += AppendNumber (start, contentObject.GetFreshness ().ToInteger (Time::S));
+      written += AppendCloser (start);
+    }
+  
   written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_PublisherPublicKeyDigest, 0, 0); // <PublisherPublicKeyDigest />
   written += AppendCloser (start);                                     // </SignedInfo>
 
@@ -229,6 +242,19 @@
   //                FreshnessSeconds?
   //                FinalBlockID?
   //                KeyLocator?
+  if (!contentObject.GetTimestamp ().IsZero())
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_Timestamp);
+      written += EstimateTimestampBlob (contentObject.GetTimestamp ());
+      written += 1;
+    }
+  if (contentObject.GetFreshness () >= Seconds(0))
+    {
+      written += EstimateBlockHeader (CcnbParser::CCN_DTAG_FreshnessSeconds);
+      written += EstimateNumber (contentObject.GetFreshness ().ToInteger (Time::S));
+      written += 1;
+    }
+
   written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_PublisherPublicKeyDigest, 0); // <PublisherPublicKeyDigest />
   written += 1;                                     // </SignedInfo>