Implementing Poisson Process for consumer requests (exponential distribution for inter-arrival times)
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 2074a39..fb92c43 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -57,11 +57,18 @@
                    IntegerValue(0),
                    MakeIntegerAccessor(&CcnxConsumer::m_seq),
                    MakeIntegerChecker<int32_t>())
-    
-    .AddAttribute ("OffTime", "Time interval between packets",
-                   StringValue ("100ms"),
-                   MakeTimeAccessor (&CcnxConsumer::m_offTime),
-                   MakeTimeChecker ())
+
+    ///////
+    .AddAttribute ("PayloadSize", "Average size of content object size (to calculate interest generation rate)",
+                   UintegerValue (1040),
+                   MakeUintegerAccessor (&CcnxConsumer::GetPayloadSize, &CcnxConsumer::SetPayloadSize),
+                   MakeUintegerChecker<uint32_t>())
+    .AddAttribute ("MeanRate", "Mean data packet rate (relies on the PayloadSize parameter)",
+                   StringValue ("100Kbps"),
+                   MakeDataRateAccessor (&CcnxConsumer::GetDesiredRate, &CcnxConsumer::SetDesiredRate),
+                   MakeDataRateChecker ())
+    ///////
+
     .AddAttribute ("Prefix","CcnxName of the Interest",
                    StringValue ("/"),
                    MakeCcnxNameComponentsAccessor (&CcnxConsumer::m_interestName),
@@ -107,9 +114,13 @@
     
 CcnxConsumer::CcnxConsumer ()
   : m_rand (0, std::numeric_limits<uint32_t>::max ())
+  , m_desiredRate ("10Kbps")
+  , m_payloadSize (1024)
   , m_seq (0)
 {
   NS_LOG_FUNCTION_NOARGS ();
+
+  UpdateMean (); // not necessary (will be called by ns3 object system anyways), but doesn't hurt
 }
 
 void
@@ -155,6 +166,49 @@
                                      &CcnxConsumer::CheckRetxTimeout, this); 
 }
 
+void
+CcnxConsumer::UpdateMean ()
+{
+  double mean = 8.0 * m_payloadSize / m_desiredRate.GetBitRate ();
+  m_randExp = ExponentialVariable (mean, 10000 * mean); // set upper limit to inter-arrival time
+}
+
+void
+CcnxConsumer::SetPayloadSize (uint32_t payload)
+{
+  m_payloadSize = payload;
+  UpdateMean ();
+}
+
+uint32_t
+CcnxConsumer::GetPayloadSize () const
+{
+  return m_payloadSize;
+}
+
+void
+CcnxConsumer::SetDesiredRate (DataRate rate)
+{
+  m_desiredRate = rate;
+  UpdateMean ();
+}
+
+DataRate
+CcnxConsumer::GetDesiredRate () const
+{
+  return m_desiredRate;
+}
+
+void
+CcnxConsumer::ScheduleNextPacket ()
+{
+  // schedule periodic packet generation
+  
+  m_sendEvent = Simulator::Schedule (
+                                     Seconds(m_randExp.GetValue ()),
+                                     &CcnxConsumer::SendPacket, this);
+}
+
 // Application Methods
 void 
 CcnxConsumer::StartApplication () // Called at time specified by Start
@@ -163,9 +217,8 @@
 
   // do base stuff
   CcnxApp::StartApplication ();
-  
-  // schedule periodic packet generation
-  m_sendEvent = Simulator::Schedule (Seconds(0.0), &CcnxConsumer::SendPacket, this);
+
+  ScheduleNextPacket ();
 }
     
 void 
@@ -233,11 +286,16 @@
     m_seqTimeouts.modify (res.first,
                           ll::bind(&SeqTimeout::time, ll::_1) = Simulator::Now ());
   
-  m_sendEvent = Simulator::Schedule (m_offTime, &CcnxConsumer::SendPacket, this);
-
   m_transmittedInterests (&interestHeader, this, m_face);
+
+  ScheduleNextPacket ();
 }
 
+///////////////////////////////////////////////////
+//          Process incoming packets             //
+///////////////////////////////////////////////////
+
+
 void
 CcnxConsumer::OnContentObject (const Ptr<const CcnxContentObjectHeader> &contentObject,
                                const Ptr<const Packet> &payload)
diff --git a/apps/ccnx-consumer.h b/apps/ccnx-consumer.h
index 7cfb739..ed1558c 100644
--- a/apps/ccnx-consumer.h
+++ b/apps/ccnx-consumer.h
@@ -25,6 +25,7 @@
 #include "ns3/random-variable.h"
 #include "ns3/ccnx-name-components.h"
 #include "ns3/nstime.h"
+#include "ns3/data-rate.h"
 
 #include <set>
 
@@ -67,6 +68,24 @@
 private:
   //helpers
   void
+  ScheduleNextPacket ();
+
+  void
+  UpdateMean ();
+
+  void
+  SetPayloadSize (uint32_t payload);
+
+  uint32_t
+  GetPayloadSize () const;
+
+  void
+  SetDesiredRate (DataRate rate);
+
+  DataRate
+  GetDesiredRate () const;
+  
+  void
   SendPacket ();
 
   void
@@ -79,7 +98,12 @@
   GetRetxTimer () const;
   
 protected:
-  UniformVariable m_rand;
+  UniformVariable m_rand; // nonce generator
+
+  ExponentialVariable m_randExp; // packet inter-arrival time generation (Poisson process)
+  DataRate            m_desiredRate;    // Desired data packet rate
+  uint32_t            m_payloadSize; // expected payload size
+  
   uint32_t        m_seq;
   EventId         m_sendEvent; // Eventid of pending "send packet" event
   Time            m_retxTimer;
diff --git a/examples/abilene-topology.cc b/examples/abilene-topology.cc
index d17f23a..48ad6db 100644
--- a/examples/abilene-topology.cc
+++ b/examples/abilene-topology.cc
@@ -46,25 +46,21 @@
   Simulator::Schedule (Seconds (10.0), PrintTime);
 }
 
-void PrintFIBs ()
-{
-  NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
-  Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
-  for (NodeList::Iterator node = NodeList::Begin ();
-       node != NodeList::End ();
-       node++)
-    {
-      // *routingStream->GetStream () << "Node " << (*node)->GetId () << "\n";
+// void PrintFIBs ()
+// {
+//   NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
+//   Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
+//   for (NodeList::Iterator node = NodeList::Begin ();
+//        node != NodeList::End ();
+//        node++)
+//     {
+//       // *routingStream->GetStream () << "Node " << (*node)->GetId () << "\n";
 
-      Ptr<CcnxFib> fib = (*node)->GetObject<CcnxFib> ();
-      NS_ASSERT_MSG (fib != 0, "Fire alarm");
-      *routingStream->GetStream () << *fib << "\n\n";
-    }
-}
-
-
-
-
+//       Ptr<CcnxFib> fib = (*node)->GetObject<CcnxFib> ();
+//       NS_ASSERT_MSG (fib != 0, "Fire alarm");
+//       *routingStream->GetStream () << *fib << "\n\n";
+//     }
+// }
 
 
 int 
@@ -88,8 +84,8 @@
   // -- Read topology data.
   // --------------------------------------------
     
-  AnnotatedTopologyReader reader ("/abilene");
-  reader.SetMobilityModel ("ns3::SpringMobilityModel");
+  AnnotatedTopologyReader reader ("/abilene", 2.0);
+  // reader.SetMobilityModel ("ns3::SpringMobilityModel");
   reader.SetFileName (input);
     
   NodeContainer nodes = reader.Read ();
@@ -100,7 +96,7 @@
       return -1;
     }
 
-  SpringMobilityHelper::InstallSprings (reader.LinksBegin (), reader.LinksEnd ());
+  // SpringMobilityHelper::InstallSprings (reader.LinksBegin (), reader.LinksEnd ());
 
   // InternetStackHelper stack;
   // Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
@@ -122,14 +118,14 @@
     
   NS_LOG_INFO ("Installing Applications");
   CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
-  consumerHelper.SetPrefix ("/5");
-  ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/abilene", "ATLAng"));
+  consumerHelper.SetPrefix ("/Data");
+  consumerHelper.SetAttribute ("MeanRate", StringValue ("1Mbps"));
+  ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/abilene", "SNVAng"));
   
   CcnxAppHelper producerHelper ("ns3::CcnxProducer");
-  producerHelper.SetPrefix ("/5");
-  producerHelper.SetAttribute ("PayloadSize", StringValue("1024"));
+  producerHelper.SetPrefix ("/Data");
 
-  ApplicationContainer producers = producerHelper.Install (Names::Find<Node> ("/abilene", "IPLSng"));
+  ApplicationContainer producers = producerHelper.Install (Names::Find<Node> ("/abilene", "NYCMng"));
 
   // // Populate FIB based on IPv4 global routing controller
   // ccnxHelper.InstallFakeGlobalRoutes ();
@@ -138,7 +134,7 @@
   // Simulator::Schedule (Seconds (1.0), PrintFIBs);
   // PrintFIBs ();
 
-  // Simulator::Schedule (Seconds (10.0), PrintTime);
+  Simulator::Schedule (Seconds (10.0), PrintTime);
 
   Simulator::Stop (finishTime);
 
@@ -149,10 +145,6 @@
       anim->SetMobilityPollInterval (Seconds (1));
     }
 
-  // NS_LOG_INFO ("Configure Tracing.");
-  // CcnxAggregateAppTracer consumerTrace ("ns3::CcnxConsumer", "*");
-  // CcnxAggregateAppTracer producerTrace ("ns3::CcnxProducer", "*");
-  // CcnxAggregateL3Tracer ccnxTrace ("1");
   CcnxTraceHelper traceHelper;
   traceHelper.EnableAggregateAppAll ("ns3::CcnxConsumer");
   traceHelper.EnableAggregateAppAll ("ns3::CcnxProducer");
@@ -167,8 +159,5 @@
   Simulator::Destroy ();
   NS_LOG_INFO ("Done.");
 
-  // NS_LOG_INFO ("ConsumerTrace: \n" << consumerTrace);
-  // NS_LOG_INFO ("ProducerTrace: \n" << producerTrace);
-  // NS_LOG_INFO ("CcnxTrace: \n" << ccnxTrace);
   return 0;
 }
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index 28a021b..a4255be 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -64,7 +64,6 @@
 {
   Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("1Mbps"));
   Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("10ms"));
-  Config::SetDefault ("ns3::CcnxConsumer::OffTime", StringValue ("1s"));
   Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("20"));
     
   Packet::EnableChecking();
@@ -118,6 +117,7 @@
   
   CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
   consumerHelper.SetPrefix (prefix.str ());
+  consumerHelper.SetAttribute ("MeanRate", StringValue ("1Mbps"));
   ApplicationContainer consumers = consumerHelper.Install (consumerNodes);
   
   // consumers.Start (Seconds (0.0));
diff --git a/examples/synthetic-topology.cc b/examples/synthetic-topology.cc
index 39c45eb..0b03c7c 100644
--- a/examples/synthetic-topology.cc
+++ b/examples/synthetic-topology.cc
@@ -91,15 +91,19 @@
   CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
 
   consumerHelper.SetPrefix ("/6");
+  consumerHelper.SetAttribute ("MeanRate", StringValue ("1Mbps"));
   ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/synthetic", "c1"));
 
   consumerHelper.SetPrefix ("/7");
+  consumerHelper.SetAttribute ("MeanRate", StringValue ("2Mbps"));
   ApplicationContainer consumers2 = consumerHelper.Install(Names::Find<Node> ("/synthetic", "c2"));
 
   consumerHelper.SetPrefix ("/8");
+  consumerHelper.SetAttribute ("MeanRate", StringValue ("3Mbps"));
   ApplicationContainer consumers3 = consumerHelper.Install(Names::Find<Node> ("/synthetic", "c3"));
   
   consumerHelper.SetPrefix ("/10");
+  consumerHelper.SetAttribute ("MeanRate", StringValue ("10Mbps"));
   ApplicationContainer consumers4 = consumerHelper.Install(Names::Find<Node> ("/synthetic", "c4"));
 
   consumers.Start (Seconds (0));
diff --git a/examples/synthetic-topology.txt b/examples/synthetic-topology.txt
index 240ef1e..a5c5446 100644
--- a/examples/synthetic-topology.txt
+++ b/examples/synthetic-topology.txt
@@ -15,7 +15,7 @@
 #capacity on 4/10/2003 (see page 20 of http://www.internet2.edu/presentations/spring03/20030410-Abilene-Corbato.pdf)
 #OSPF weight on 04/10/2003 (see http://www.abilene.iu.edu/images/Ab-IGP-topo.jpg)
 #x	y	capacity(kbps)	OSPF    Delay		MaxPackets
-c1	n1	10Mbps 		1 	1ms  		200
+c1	n1	10Mbps 		1 	50ms  		200
 c2	n1	10Mbps 		1 	1ms   		200
 c3	n1	10Mbps		1	1ms		200
 n1	n2	1Mbps 		1176   	1ms   		20 
diff --git a/model/annotated-topology-reader.cc b/model/annotated-topology-reader.cc
index edcff58..2ca17eb 100644
--- a/model/annotated-topology-reader.cc
+++ b/model/annotated-topology-reader.cc
@@ -52,10 +52,11 @@
 
 NS_LOG_COMPONENT_DEFINE ("AnnotatedTopologyReader");
     
-AnnotatedTopologyReader::AnnotatedTopologyReader (const std::string &path)
+AnnotatedTopologyReader::AnnotatedTopologyReader (const std::string &path, double scale/*=1.0*/)
   : m_path (path)
   , m_randX (0, 100.0)
   , m_randY (0, 100.0)
+  , m_scale (scale)
 {
   NS_LOG_FUNCTION (this);
 
@@ -137,7 +138,7 @@
       double latitude, longitude;
 
       lineBuffer >> name >> city >> latitude >> longitude;
-      Ptr<Node> node = CreateNode (name, longitude, -latitude);
+      Ptr<Node> node = CreateNode (name, m_scale*longitude, -m_scale*latitude);
       nodes.Add (node);
     }
 
diff --git a/model/annotated-topology-reader.h b/model/annotated-topology-reader.h
index 4bacd2a..cbcd890 100644
--- a/model/annotated-topology-reader.h
+++ b/model/annotated-topology-reader.h
@@ -39,10 +39,11 @@
    * \brief Constructor
    *
    * \param path ns3::Names path
+   * \param scale Scaling factor for coordinates in input file
    *
    * \see ns3::Names class
    */
-  AnnotatedTopologyReader (const std::string &path="");
+  AnnotatedTopologyReader (const std::string &path="", double scale=1.0);
   virtual ~AnnotatedTopologyReader ();
         
   /**
@@ -100,6 +101,7 @@
   UniformVariable m_randY;
 
   ObjectFactory m_mobilityFactory;
+  double m_scale;
 };
 
 }