Enabling app-layer tracing

Network-layer tracing is not working yet (needs a couple of attributes
to be implemented)
diff --git a/apps/ccnx-app.cc b/apps/ccnx-app.cc
index 40c1168..780eb9f 100644
--- a/apps/ccnx-app.cc
+++ b/apps/ccnx-app.cc
@@ -42,6 +42,15 @@
   static TypeId tid = TypeId ("ns3::CcnxApp")
     .SetParent<Application> ()
     .AddConstructor<CcnxApp> ()
+
+    .AddTraceSource ("ReceivedInterests", "ReceivedInterests",
+                    MakeTraceSourceAccessor (&CcnxApp::m_receivedInterests))
+    
+    .AddTraceSource ("ReceivedNacks", "ReceivedNacks",
+                    MakeTraceSourceAccessor (&CcnxApp::m_receivedNacks))
+    
+    .AddTraceSource ("ReceivedContentObjects", "ReceivedContentObjects",
+                    MakeTraceSourceAccessor (&CcnxApp::m_receivedContentObjects))
     ;
   return tid;
 }
@@ -78,12 +87,14 @@
 CcnxApp::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
 {
   NS_LOG_FUNCTION (this << interest);
+  m_receivedInterests (interest, this, m_face);
 }
 
 void
 CcnxApp::OnNack (const Ptr<const CcnxInterestHeader> &interest)
 {
   NS_LOG_FUNCTION (this << interest);
+  m_receivedNacks (interest, this, m_face);
 }
 
 void
@@ -91,6 +102,7 @@
                           const Ptr<const Packet> &payload)
 {
   NS_LOG_FUNCTION (this << contentObject << payload);
+  m_receivedContentObjects (contentObject, payload, this, m_face);
 }
 
 // Application Methods
diff --git a/apps/ccnx-app.h b/apps/ccnx-app.h
index f94018f..457172e 100644
--- a/apps/ccnx-app.h
+++ b/apps/ccnx-app.h
@@ -24,6 +24,7 @@
 #include "ns3/application.h"
 #include "ns3/ptr.h"
 #include "ns3/callback.h"
+#include "ns3/traced-callback.h"
 
 namespace ns3 
 {
@@ -96,6 +97,15 @@
   ProtocolHandler m_protocolHandler;
   bool m_active; 
   Ptr<CcnxFace> m_face; // local face that is created 
+
+  TracedCallback<Ptr<const CcnxInterestHeader>,
+                 Ptr<CcnxApp>, Ptr<CcnxFace> > m_receivedInterests;
+
+  TracedCallback<Ptr<const CcnxInterestHeader>,
+                 Ptr<CcnxApp>, Ptr<CcnxFace> > m_receivedNacks;
+
+  TracedCallback<Ptr<const CcnxContentObjectHeader>, Ptr<const Packet>,
+                 Ptr<CcnxApp>, Ptr<CcnxFace> > m_receivedContentObjects;
 };
 
 } // namespace ns3
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 7e541ec..28211e4 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -51,7 +51,7 @@
 CcnxConsumer::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxConsumer")
-    .SetParent<Application> ()
+    .SetParent<CcnxApp> ()
     .AddConstructor<CcnxConsumer> ()
     .AddAttribute ("StartSeq", "Initial sequence number",
                    IntegerValue(0),
@@ -98,12 +98,8 @@
                    MakeTimeAccessor (&CcnxConsumer::GetRetxTimer, &CcnxConsumer::SetRetxTimer),
                    MakeTimeChecker ())
 
-    // .AddTraceSource ("InterestTrace", "Interests that were sent",
-    //                  MakeTraceSourceAccessor (&CcnxConsumer::m_interestsTrace))
-    // .AddTraceSource ("NackTrace", "NACKs received",
-    //                  MakeTraceSourceAccessor (&CcnxConsumer::m_nackTrace))
-    // .AddTraceSource ("ContentObjectTrace", "ContentObjects received",
-    //                  MakeTraceSourceAccessor (&CcnxConsumer::m_contentObjectsTrace))
+    .AddTraceSource ("TransmittedInterests", "TransmittedInterests",
+                    MakeTraceSourceAccessor (&CcnxConsumer::m_transmittedInterests))
     ;
 
   return tid;
@@ -139,6 +135,8 @@
 {
   Time now = Simulator::Now ();
 
+  boost::mutex::scoped_lock (m_seqTimeoutsGuard);
+
   while (!m_seqTimeouts.empty ())
     {
       SeqTimeoutsContainer::index<i_timestamp>::type::iterator entry =
@@ -187,6 +185,8 @@
 {
   NS_LOG_FUNCTION_NOARGS ();
 
+  boost::mutex::scoped_lock (m_seqTimeoutsGuard);
+
   uint32_t seq;
   
   if (m_retxSeqs.size () != 0)
@@ -209,7 +209,7 @@
   interestHeader.SetChildSelector       (m_childSelector);
   if (m_exclude.size ()>0)
     {
-      interestHeader.SetExclude             (Create<CcnxNameComponents> (m_exclude));
+      interestHeader.SetExclude (Create<CcnxNameComponents> (m_exclude));
     }
   interestHeader.SetMaxSuffixComponents (m_maxSuffixComponents);
   interestHeader.SetMinSuffixComponents (m_minSuffixComponents);
@@ -222,21 +222,26 @@
 
   m_protocolHandler (packet);
 
+  NS_LOG_DEBUG ("Trying to add " << seq << " with " << Simulator::Now () << ". already " << m_seqTimeouts.size () << " items");  
+  
   std::pair<SeqTimeoutsContainer::iterator, bool>
     res = m_seqTimeouts.insert (SeqTimeout (seq, Simulator::Now ()));
-  if (!res.second)
-    m_seqTimeouts.modify (res.first,
-                          ll::bind(&SeqTimeout::time, ll::_1) = Simulator::Now ());
+  
+  // if (!res.second)
+  //   m_seqTimeouts.modify (res.first,
+  //                         ll::bind(&SeqTimeout::time, ll::_1) = Simulator::Now ());
   
   m_sendEvent = Simulator::Schedule (m_offTime, &CcnxConsumer::SendPacket, this);
 
-  // \todo Trace
+  m_transmittedInterests (&interestHeader, this, m_face);
 }
 
 void
 CcnxConsumer::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
                                const Ptr<const Packet> &payload)
 {
+  CcnxApp::OnContentObject (contentObject, payload); // tracing inside
+  
   NS_LOG_FUNCTION (this << contentObject << payload);
 
   // NS_LOG_INFO ("Received content object: " << boost::cref(*contentObject));
@@ -244,6 +249,8 @@
   uint32_t seq = boost::lexical_cast<uint32_t> (contentObject->GetName ().GetComponents ().back ());
   NS_LOG_INFO ("< DATA for " << seq);
 
+  boost::mutex::scoped_lock (m_seqTimeoutsGuard);
+  
   SeqTimeoutsContainer::iterator entry = m_seqTimeouts.find (seq);
 
   NS_ASSERT_MSG (entry != m_seqTimeouts.end (),
@@ -251,13 +258,13 @@
 
   if (entry != m_seqTimeouts.end ())
     m_seqTimeouts.erase (entry);
-
-  // \todo Trace
 }
 
 void
 CcnxConsumer::OnNack (const Ptr<const CcnxInterestHeader> &interest)
 {
+  CcnxApp::OnNack (interest); // tracing inside
+  
   NS_LOG_FUNCTION (this << interest);
 
   // NS_LOG_INFO ("Received NACK: " << boost::cref(*interest));
@@ -266,8 +273,6 @@
 
   // put in the queue of interests to be retransmitted
   m_retxSeqs.insert (seq);
-
-  // \todo Trace?
 }
 
 } // namespace ns3
diff --git a/apps/ccnx-consumer.h b/apps/ccnx-consumer.h
index ce0a20c..7cfb739 100644
--- a/apps/ccnx-consumer.h
+++ b/apps/ccnx-consumer.h
@@ -33,6 +33,8 @@
 #include <boost/multi_index/ordered_index.hpp>
 #include <boost/multi_index/member.hpp>
 
+#include <boost/thread/mutex.hpp>
+
 namespace ns3 
 {
 
@@ -106,8 +108,6 @@
     
     uint32_t seq;
     Time time;
-
-    bool operator < (const SeqTimeout &st) { return time < st.time || (time == st.time && seq < st.seq); }
   };
 
   class i_seq { };
@@ -129,6 +129,10 @@
     > { } ;
 
   SeqTimeoutsContainer m_seqTimeouts;
+  boost::mutex m_seqTimeoutsGuard;
+
+  TracedCallback<Ptr<const CcnxInterestHeader>,
+                 Ptr<CcnxApp>, Ptr<CcnxFace> > m_transmittedInterests;
 };
 
 } // namespace ns3
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index ba2918d..3a37efd 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -53,10 +53,9 @@
                    UintegerValue (1024),
                    MakeUintegerAccessor(&CcnxProducer::m_virtualPayloadSize),
                    MakeUintegerChecker<uint32_t>())
-    // .AddTraceSource ("InterestTrace", "Interests that were received",
-    //                 MakeTraceSourceAccessor (&CcnxProducer::m_interestsTrace))
-    // .AddTraceSource ("ContentObjectTrace", "ContentObjects that were sent",
-    //                 MakeTraceSourceAccessor (&CcnxProducer::m_contentObjectsTrace))
+    
+    .AddTraceSource ("TransmittedContentObjects", "TransmittedContentObjects",
+                    MakeTraceSourceAccessor (&CcnxProducer::m_transmittedContentObjects))
     ;
         
   return tid;
@@ -92,6 +91,8 @@
 void
 CcnxProducer::OnInterest (const Ptr<const CcnxInterestHeader> &interest)
 {
+  CcnxApp::OnInterest (interest); // tracing inside
+
   NS_LOG_FUNCTION (this << interest);
 
   if (!m_active) return;
@@ -103,6 +104,9 @@
   NS_LOG_INFO ("Respodning with ContentObject:\n" << boost::cref(*header));
   
   Ptr<Packet> packet = Create<Packet> (m_virtualPayloadSize);
+
+  m_transmittedContentObjects (header, packet, this, m_face);
+  
   packet->AddHeader (*header);
   packet->AddTrailer (tail);
 
diff --git a/apps/ccnx-producer.h b/apps/ccnx-producer.h
index ac9a492..a239d84 100644
--- a/apps/ccnx-producer.h
+++ b/apps/ccnx-producer.h
@@ -52,6 +52,9 @@
 private:
   CcnxNameComponents m_prefix;
   uint32_t m_virtualPayloadSize;
+
+  TracedCallback<Ptr<const CcnxContentObjectHeader>, Ptr<const Packet>,
+                 Ptr<CcnxApp>, Ptr<CcnxFace> > m_transmittedContentObjects;
 };
 
 }