Update of BlackholeSprint scenario.  Extending CcnxStackHelper API
(InstallRouteTo can now accept prefix as a parameter)
diff --git a/examples/blackhole-sprint.cc b/examples/blackhole-sprint.cc
index f97be29..a6afb82 100644
--- a/examples/blackhole-sprint.cc
+++ b/examples/blackhole-sprint.cc
@@ -27,7 +27,6 @@
 #include "ns3/ipv4-global-routing-helper.h"
 #include "ns3/random-variable.h"
 
-#include <iostream>
 #include <sstream>
 #include <map>
 #include <list>
@@ -50,209 +49,74 @@
   Simulator::Schedule (Seconds (1.0), PrintTime);
 }
 
+#include "base-experiment.h"
 
-class Experiment
+class Experiment : public BaseExperiment
 {
 public:
-  Experiment ()
-  : m_reader ("/sprint") { }
-
-  void
-  ConfigureTopology ()
-  {
-    Names::Clear ();
-    
-    string weights   ("./src/NDNabstraction/examples/sprint-pops.weights");
-    string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
-    string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
-
-    m_reader.SetFileName (positions);
-    m_reader.SetFileType (RocketfuelWeightsReader::POSITIONS);
-    m_reader.Read ();
-  
-    m_reader.SetFileName (weights);
-    m_reader.SetFileType (RocketfuelWeightsReader::WEIGHTS);    
-    m_reader.Read ();
-
-    m_reader.SetFileName (latencies);
-    m_reader.SetFileType (RocketfuelWeightsReader::LATENCIES);    
-    m_reader.Read ();
-    
-    m_reader.Commit ();
-    NS_ASSERT_MSG (m_reader.LinksSize () != 0, "Problems reading the topology file. Failing.");
-    
-    NS_LOG_INFO("Nodes = " << m_reader.GetNodes ().GetN());
-    NS_LOG_INFO("Links = " << m_reader.LinksSize ());
-  
-    // ------------------------------------------------------------
-    // -- Read topology data.
-    // --------------------------------------------
-        
-    InternetStackHelper stack;
-    Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
-    stack.SetRoutingHelper (ipv4RoutingHelper);
-    stack.Install (m_reader.GetNodes ());
-
-    m_reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-    
-    // Install CCNx stack
-    NS_LOG_INFO ("Installing CCNx stack");
-    CcnxStackHelper ccnxHelper;
-    ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
-    ccnxHelper.EnableLimits (true, Seconds(0.1));
-    ccnxHelper.SetDefaultRoutes (false);
-    ccnxHelper.InstallAll ();
-    
-    m_rand = UniformVariable (0, m_reader.GetNodes ().GetN());
-    m_linkRand = UniformVariable(0, m_reader.LinksSize());
-  }
-
-  void
-  ConfigureRouting ()
-  {
-    CcnxStackHelper ccnxHelper;
-    // // Populate FIB based on IPv4 global routing controller
-    ccnxHelper.InstallFakeGlobalRoutes ();
-    ccnxHelper.InstallRoutesToAll ();
-  }
-
-public:  
-  void
-  Run (const Time &finishTime)
-  {
-    cout << "Run Simulation.\n";
-    Simulator::Stop (finishTime);
-    //Simulator::Schedule (Seconds (1.0), PrintTime);
-    Simulator::Run ();
-    Simulator::Destroy ();
-    cout << "Done.\n";
-  }
-
   //We are creating 10 pairs of producer-hijacker and everybody else is a consumer
   ApplicationContainer
-  AddApplications(uint32_t numOfPairs)
+  AddApplications ()
   {
-    NS_LOG_INFO("Adding applications");
     ApplicationContainer apps;
-    
-    list<uint32_t > usedNodes;
-    list<uint32_t >::iterator listIterator;
-    list<uint32_t >::iterator listIterator2;
-    
-    uint32_t producerNodeId;
-    uint32_t hijackerNodeId;
 
-    for(uint32_t pairCount = 0; pairCount < numOfPairs; pairCount++)
+    list<string> prefixes;
+
+    // Create Producers/Hijackers
+    for (list<tuple<uint32_t,uint32_t> >::iterator i = m_pairs.begin (); i != m_pairs.end (); i++)
       {
-        NS_LOG_INFO("pairCount = "<<pairCount);
-        while(true)
-          {
-            producerNodeId = m_rand.GetValue ();
-            hijackerNodeId = m_rand.GetValue ();
-        
-            bool unique = true; 
-            for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator)
-              {
-                if((*listIterator == producerNodeId) || (*listIterator == hijackerNodeId))
-                  {
-                    NS_LOG_INFO("NonUnique");
-                    unique = false;
-                  }
-              }
-        
-            if(unique == true)
-              {
-                usedNodes.push_back(producerNodeId);
-                usedNodes.push_back(hijackerNodeId);
-                break;
-              }
-          }
-      
-        NS_LOG_INFO("Producer #" << producerNodeId);
-        Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (producerNodeId));
-        CcnxAppHelper producerHelper ("ns3::CcnxProducer");
-        producerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-        
-        apps.Add(producerHelper.Install (node1));
+        uint32_t node1_num = i->get<0> ();
+        uint32_t node2_num = i->get<1> ();
 
-        NS_LOG_INFO("Hijacker # "<<hijackerNodeId);
-        Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (hijackerNodeId));
-        CcnxAppHelper hijackerHelper ("ns3::CcnxHijacker");
-        hijackerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-        
-        apps.Add(hijackerHelper.Install (node1));
-        
-        /*NS_LOG_INFO("Consumers");
-        for(uint32_t j = 0; j<m_reader.GetNodes().GetN();j++)
-          {
-            //NS_LOG_INFO("j="<<j);
-            bool consumer = true;
-            for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator)
-              {
-                if(*listIterator == j)
-                {
-                  consumer = false;
-                  NS_LOG_INFO(j<<" CANNOT be CONSUMER");
-                  break;
-                }
-              }
-        
-            if(consumer == true)
-              {
-                Ptr<Node> node3 = Names::Find<Node> ("/sprint", lexical_cast<string> (j));
-        
-                CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
-                consumerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-                consumerHelper.SetAttribute ("MeanRate", StringValue ("1Kbps"));
-                consumerHelper.SetAttribute ("Size", StringValue ("2"));  
-        
-                apps.Add(consumerHelper.Install (node3));
-              }
-          }*/
-        }
-      
-      NS_LOG_INFO("Consumers");
-      for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator,++listIterator)
-        {
-          for(uint32_t j = 0; j<m_reader.GetNodes().GetN();j++)
-          {
-            //NS_LOG_INFO("j="<<j);
-            bool consumer = true;
-            for(listIterator2=usedNodes.begin(); listIterator2 != usedNodes.end(); ++listIterator2)
-              {
-                if(*listIterator2 == j)
-                {
-                  consumer = false;
-                  NS_LOG_INFO(j<<" CANNOT be a CONSUMER");
-                  break;
-                }
-              }
-        
-            if(consumer == true)
-              {
-                Ptr<Node> node3 = Names::Find<Node> ("/sprint", lexical_cast<string> (j));
-                Ptr<Node> node4 = Names::Find<Node> ("/sprint", lexical_cast<string> (*listIterator));
+        Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
+        Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
 
-                CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
-                NS_LOG_INFO("Node = " << *listIterator);
-                consumerHelper.SetPrefix ("/" + lexical_cast<string> (node4->GetId ()));
-                consumerHelper.SetAttribute ("MeanRate", StringValue ("1Kbps"));
-                consumerHelper.SetAttribute ("Size", StringValue ("2"));  
+        // node1 legitimate producer
+        // node2 "fake" producer
+
+        string prefix = "/" + lexical_cast<string> (node1->GetId ());
+
+        CcnxAppHelper legitimateProducerHelper ("ns3::CcnxProducer");
+        legitimateProducerHelper.SetPrefix (prefix);
+        apps.Add
+          (legitimateProducerHelper.Install (node1));
         
-                apps.Add(consumerHelper.Install (node3));
-              }
+        CcnxAppHelper fakeProducerHelper ("ns3::CcnxHijacker");
+        fakeProducerHelper.SetPrefix (prefix);
+        apps.Add
+          (fakeProducerHelper.Install (node2));
+        
+        // one more trick. Need to install route to hijacker (aka "hijacker announces itself as a legitimate producer")
+        CcnxStackHelper::InstallRouteTo (prefix, node2);
+
+        prefixes.push_back (prefix); // remember prefixes that consumers will be requesting
+      }
+
+    // All consumers request exactly 10 packets, to convert number interests packets to requested size:
+    // size = 1040 * (max_number_of_packets-1) / 1024 / 1024
+    double requestSize = 1040.0 * (10 - 1) / 1024.0 / 1024.0;
+    
+    // Create Consumers
+    NodeContainer nodes = reader->GetNodes ();
+    for (NodeContainer::Iterator node = nodes.Begin (); node != nodes.End (); node++)
+      {
+        uint32_t namedId = lexical_cast<uint32_t> (Names::FindName (*node));
+        if (m_usedNodes.count (namedId) > 0)
+          continue;
+
+        CcnxAppHelper consumerHelper ("ns3::CcnxConsumerCbr");
+        BOOST_FOREACH (const string &prefix, prefixes)
+          {
+            consumerHelper.SetPrefix (prefix);
+            consumerHelper.SetAttribute ("MeanRate", StringValue ("8Kbps")); // this is about 1 interest a second
+            consumerHelper.SetAttribute ("Size", DoubleValue(requestSize));
+            
+            apps.Add
+              (consumerHelper.Install (*node));
           }
-        }
-      
-      
+      }
     return apps;
   }
-
-  UniformVariable m_rand;
-  UniformVariable m_linkRand;
-  
-private:
-  RocketfuelWeightsReader m_reader;
 };
 
 int 
@@ -260,48 +124,45 @@
 {
   cout << "Begin blackhole scenario\n";
   
-  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("2Mbps"));
-  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("100"));
+  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("100Mbps"));
+  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("2000"));
 
-  Time finishTime = Seconds (20.0);
-  
-   
+  Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("attributes.xml"));
+  Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
+  Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml"));
+
+  uint32_t maxRuns = 1;
+  uint32_t startRun = 0;
   CommandLine cmd;
-  cmd.AddValue ("finish", "Finish time", finishTime);
+  cmd.AddValue ("start", "Initial run number", startRun);
+  cmd.AddValue ("runs", "Number of runs", maxRuns);
   cmd.Parse (argc, argv);
 
-  Experiment experiment;
+  // ConfigStore config;
+  // config.ConfigureDefaults ();
 
+  Experiment experiment;
   for (uint32_t i = 0; i < 80; i++)
     {
       Config::SetGlobal ("RngRun", IntegerValue (i));
       cout << "seed = " << SeedManager::GetSeed () << ", run = " << SeedManager::GetRun () << endl;
 
       Experiment experiment;
+      experiment.GenerateRandomPairs (10);
       cout << "Run " << i << endl;
       
       string prefix = "run-" + lexical_cast<string> (i) + "-";
   
       experiment.ConfigureTopology ();
-      ApplicationContainer apps = experiment.AddApplications (10);
-      experiment.ConfigureRouting ();
-      
-      /*ApplicationContainer apps = experiment.AddApplications ();
-
-      for (uint32_t i = 0; i < apps.GetN () / 2; i++) 
-        {
-          cout << "From " << apps.Get (i*2)->GetNode ()->GetId ()
-               << " to "  << apps.Get (i*2 + 1)->GetNode ()->GetId ();
-          cout << "\n";
-        }
-      */
-      
+      experiment.InstallCcnxStack ();
+      ApplicationContainer apps = experiment.AddApplications ();
+            
       //tracing
       CcnxTraceHelper traceHelper;
-      traceHelper.EnableRateL3All (prefix + "rate-trace.log");
+      // traceHelper.EnableRateL3All (prefix + "rate-trace.log");
       traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumer", prefix + "consumers-seqs.log");
       
-      experiment.Run (finishTime);
+      experiment.Run (Seconds(20.0));
     }
 
   cout << "Finish blackhole scenario\n";