Adding support for Timestamp and Freshness in ContentObject
diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
index 58fde33..e86e16b 100644
--- a/bindings/modulegen__gcc_ILP32.py
+++ b/bindings/modulegen__gcc_ILP32.py
@@ -330,6 +330,8 @@
     module.add_class('CcnxConsumerWindowTracer', parent=root_module['ns3::WindowTracer'])
     ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader [class]
     module.add_class('CcnxContentObjectHeader', parent=root_module['ns3::Header'])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo [struct]
+    module.add_class('SignedInfo', outer_class=root_module['ns3::CcnxContentObjectHeader'])
     ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectTail [class]
     module.add_class('CcnxContentObjectTail', parent=root_module['ns3::Trailer'])
     ## ccnx-face.h (module 'NDNabstraction'): ns3::CcnxFace [class]
@@ -624,6 +626,7 @@
     register_Ns3CcnxAppTracer_methods(root_module, root_module['ns3::CcnxAppTracer'])
     register_Ns3CcnxConsumerWindowTracer_methods(root_module, root_module['ns3::CcnxConsumerWindowTracer'])
     register_Ns3CcnxContentObjectHeader_methods(root_module, root_module['ns3::CcnxContentObjectHeader'])
+    register_Ns3CcnxContentObjectHeaderSignedInfo_methods(root_module, root_module['ns3::CcnxContentObjectHeader::SignedInfo'])
     register_Ns3CcnxContentObjectTail_methods(root_module, root_module['ns3::CcnxContentObjectTail'])
     register_Ns3CcnxFace_methods(root_module, root_module['ns3::CcnxFace'])
     register_Ns3CcnxFaceContainer_methods(root_module, root_module['ns3::CcnxFaceContainer'])
@@ -2539,11 +2542,6 @@
                    'bool', 
                    [], 
                    is_static=True)
-    ## simulator.h (module 'core'): static ns3::Time ns3::Simulator::Next() [member function]
-    cls.add_method('Next', 
-                   'ns3::Time', 
-                   [], 
-                   is_static=True, deprecated=True)
     ## simulator.h (module 'core'): static ns3::Time ns3::Simulator::Now() [member function]
     cls.add_method('Now', 
                    'ns3::Time', 
@@ -2554,11 +2552,6 @@
                    'void', 
                    [param('ns3::EventId const &', 'id')], 
                    is_static=True)
-    ## simulator.h (module 'core'): static void ns3::Simulator::RunOneEvent() [member function]
-    cls.add_method('RunOneEvent', 
-                   'void', 
-                   [], 
-                   is_static=True, deprecated=True)
     ## simulator.h (module 'core'): static void ns3::Simulator::SetImplementation(ns3::Ptr<ns3::SimulatorImpl> impl) [member function]
     cls.add_method('SetImplementation', 
                    'void', 
@@ -5039,6 +5032,11 @@
                    'uint32_t', 
                    [param('ns3::Buffer::Iterator', 'start')], 
                    is_virtual=True)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::Time ns3::CcnxContentObjectHeader::GetFreshness() const [member function]
+    cls.add_method('GetFreshness', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::TypeId ns3::CcnxContentObjectHeader::GetInstanceTypeId() const [member function]
     cls.add_method('GetInstanceTypeId', 
                    'ns3::TypeId', 
@@ -5054,6 +5052,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::Time ns3::CcnxContentObjectHeader::GetTimestamp() const [member function]
+    cls.add_method('GetTimestamp', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## ccnx-content-object-header.h (module 'NDNabstraction'): static ns3::TypeId ns3::CcnxContentObjectHeader::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -5069,10 +5072,29 @@
                    'void', 
                    [param('ns3::Buffer::Iterator', 'start')], 
                    is_const=True, is_virtual=True)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): void ns3::CcnxContentObjectHeader::SetFreshness(ns3::Time const & freshness) [member function]
+    cls.add_method('SetFreshness', 
+                   'void', 
+                   [param('ns3::Time const &', 'freshness')])
     ## ccnx-content-object-header.h (module 'NDNabstraction'): void ns3::CcnxContentObjectHeader::SetName(ns3::Ptr<ns3::CcnxNameComponents> const & name) [member function]
     cls.add_method('SetName', 
                    'void', 
                    [param('ns3::Ptr< ns3::CcnxNameComponents > const &', 'name')])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): void ns3::CcnxContentObjectHeader::SetTimestamp(ns3::Time const & timestamp) [member function]
+    cls.add_method('SetTimestamp', 
+                   'void', 
+                   [param('ns3::Time const &', 'timestamp')])
+    return
+
+def register_Ns3CcnxContentObjectHeaderSignedInfo_methods(root_module, cls):
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::SignedInfo() [constructor]
+    cls.add_constructor([])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::SignedInfo(ns3::CcnxContentObjectHeader::SignedInfo const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CcnxContentObjectHeader::SignedInfo const &', 'arg0')])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::m_freshness [variable]
+    cls.add_instance_attribute('m_freshness', 'ns3::Time', is_const=False)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::m_timestamp [variable]
+    cls.add_instance_attribute('m_timestamp', 'ns3::Time', is_const=False)
     return
 
 def register_Ns3CcnxContentObjectTail_methods(root_module, cls):
diff --git a/bindings/modulegen__gcc_LP64.py b/bindings/modulegen__gcc_LP64.py
index 58fde33..e86e16b 100644
--- a/bindings/modulegen__gcc_LP64.py
+++ b/bindings/modulegen__gcc_LP64.py
@@ -330,6 +330,8 @@
     module.add_class('CcnxConsumerWindowTracer', parent=root_module['ns3::WindowTracer'])
     ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader [class]
     module.add_class('CcnxContentObjectHeader', parent=root_module['ns3::Header'])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo [struct]
+    module.add_class('SignedInfo', outer_class=root_module['ns3::CcnxContentObjectHeader'])
     ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectTail [class]
     module.add_class('CcnxContentObjectTail', parent=root_module['ns3::Trailer'])
     ## ccnx-face.h (module 'NDNabstraction'): ns3::CcnxFace [class]
@@ -624,6 +626,7 @@
     register_Ns3CcnxAppTracer_methods(root_module, root_module['ns3::CcnxAppTracer'])
     register_Ns3CcnxConsumerWindowTracer_methods(root_module, root_module['ns3::CcnxConsumerWindowTracer'])
     register_Ns3CcnxContentObjectHeader_methods(root_module, root_module['ns3::CcnxContentObjectHeader'])
+    register_Ns3CcnxContentObjectHeaderSignedInfo_methods(root_module, root_module['ns3::CcnxContentObjectHeader::SignedInfo'])
     register_Ns3CcnxContentObjectTail_methods(root_module, root_module['ns3::CcnxContentObjectTail'])
     register_Ns3CcnxFace_methods(root_module, root_module['ns3::CcnxFace'])
     register_Ns3CcnxFaceContainer_methods(root_module, root_module['ns3::CcnxFaceContainer'])
@@ -2539,11 +2542,6 @@
                    'bool', 
                    [], 
                    is_static=True)
-    ## simulator.h (module 'core'): static ns3::Time ns3::Simulator::Next() [member function]
-    cls.add_method('Next', 
-                   'ns3::Time', 
-                   [], 
-                   is_static=True, deprecated=True)
     ## simulator.h (module 'core'): static ns3::Time ns3::Simulator::Now() [member function]
     cls.add_method('Now', 
                    'ns3::Time', 
@@ -2554,11 +2552,6 @@
                    'void', 
                    [param('ns3::EventId const &', 'id')], 
                    is_static=True)
-    ## simulator.h (module 'core'): static void ns3::Simulator::RunOneEvent() [member function]
-    cls.add_method('RunOneEvent', 
-                   'void', 
-                   [], 
-                   is_static=True, deprecated=True)
     ## simulator.h (module 'core'): static void ns3::Simulator::SetImplementation(ns3::Ptr<ns3::SimulatorImpl> impl) [member function]
     cls.add_method('SetImplementation', 
                    'void', 
@@ -5039,6 +5032,11 @@
                    'uint32_t', 
                    [param('ns3::Buffer::Iterator', 'start')], 
                    is_virtual=True)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::Time ns3::CcnxContentObjectHeader::GetFreshness() const [member function]
+    cls.add_method('GetFreshness', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::TypeId ns3::CcnxContentObjectHeader::GetInstanceTypeId() const [member function]
     cls.add_method('GetInstanceTypeId', 
                    'ns3::TypeId', 
@@ -5054,6 +5052,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::Time ns3::CcnxContentObjectHeader::GetTimestamp() const [member function]
+    cls.add_method('GetTimestamp', 
+                   'ns3::Time', 
+                   [], 
+                   is_const=True)
     ## ccnx-content-object-header.h (module 'NDNabstraction'): static ns3::TypeId ns3::CcnxContentObjectHeader::GetTypeId() [member function]
     cls.add_method('GetTypeId', 
                    'ns3::TypeId', 
@@ -5069,10 +5072,29 @@
                    'void', 
                    [param('ns3::Buffer::Iterator', 'start')], 
                    is_const=True, is_virtual=True)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): void ns3::CcnxContentObjectHeader::SetFreshness(ns3::Time const & freshness) [member function]
+    cls.add_method('SetFreshness', 
+                   'void', 
+                   [param('ns3::Time const &', 'freshness')])
     ## ccnx-content-object-header.h (module 'NDNabstraction'): void ns3::CcnxContentObjectHeader::SetName(ns3::Ptr<ns3::CcnxNameComponents> const & name) [member function]
     cls.add_method('SetName', 
                    'void', 
                    [param('ns3::Ptr< ns3::CcnxNameComponents > const &', 'name')])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): void ns3::CcnxContentObjectHeader::SetTimestamp(ns3::Time const & timestamp) [member function]
+    cls.add_method('SetTimestamp', 
+                   'void', 
+                   [param('ns3::Time const &', 'timestamp')])
+    return
+
+def register_Ns3CcnxContentObjectHeaderSignedInfo_methods(root_module, cls):
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::SignedInfo() [constructor]
+    cls.add_constructor([])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::SignedInfo(ns3::CcnxContentObjectHeader::SignedInfo const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::CcnxContentObjectHeader::SignedInfo const &', 'arg0')])
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::m_freshness [variable]
+    cls.add_instance_attribute('m_freshness', 'ns3::Time', is_const=False)
+    ## ccnx-content-object-header.h (module 'NDNabstraction'): ns3::CcnxContentObjectHeader::SignedInfo::m_timestamp [variable]
+    cls.add_instance_attribute('m_timestamp', 'ns3::Time', is_const=False)
     return
 
 def register_Ns3CcnxContentObjectTail_methods(root_module, cls):
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>
 
diff --git a/model/ccnx-content-object-header.cc b/model/ccnx-content-object-header.cc
index 767d512..ca013e8 100644
--- a/model/ccnx-content-object-header.cc
+++ b/model/ccnx-content-object-header.cc
@@ -61,6 +61,31 @@
   return *m_name;
 }
 
+void
+CcnxContentObjectHeader::SetTimestamp (const Time &timestamp)
+{
+  m_signedInfo.m_timestamp = timestamp;
+}
+
+Time
+CcnxContentObjectHeader::GetTimestamp () const
+{
+  return m_signedInfo.m_timestamp;
+}
+
+void
+CcnxContentObjectHeader::SetFreshness (const Time &freshness)
+{
+  m_signedInfo.m_freshness = freshness;
+}
+
+Time
+CcnxContentObjectHeader::GetFreshness () const
+{
+  return m_signedInfo.m_freshness;
+}
+
+
 uint32_t
 CcnxContentObjectHeader::GetSerializedSize (void) const
 {
diff --git a/model/ccnx-content-object-header.h b/model/ccnx-content-object-header.h
index f71e483..324f766 100644
--- a/model/ccnx-content-object-header.h
+++ b/model/ccnx-content-object-header.h
@@ -25,6 +25,7 @@
 #include "ns3/integer.h"
 #include "ns3/header.h"
 #include "ns3/trailer.h"
+#include "ns3/nstime.h"
 
 #include <string>
 #include <vector>
@@ -77,11 +78,17 @@
   // ?
   // GetSignature () const;
 
-  // void
-  // SetSignedInfo ();
+  void
+  SetTimestamp (const Time &timestamp);
 
-  // ?
-  // GetSignedInfo () const;
+  Time
+  GetTimestamp () const;
+  
+  void
+  SetFreshness (const Time &freshness);
+
+  Time
+  GetFreshness () const;
   
   //////////////////////////////////////////////////////////////////
   
@@ -92,10 +99,20 @@
   virtual void Serialize (Buffer::Iterator start) const;
   virtual uint32_t Deserialize (Buffer::Iterator start);
 
+  struct SignedInfo
+  {
+    // PublisherPublicKeyDigest
+    Time m_timestamp;
+    // Type (ContentType)
+    Time m_freshness;
+    // FinalBlockID
+    // KeyLocator
+  };
+  
 private:
-  Ptr<CcnxNameComponents> m_name;
   // m_signature;
-  // m_signedInfo;
+  Ptr<CcnxNameComponents> m_name;
+  SignedInfo m_signedInfo;
 };
 
 /**