Modifying SpringMobilityModel to make all nodes readjust after even one
node changes its position (previously only this node was adjusting itself)

SpringMobilityModel now updates positions based on internal (static) timer
diff --git a/model/annotated-topology-reader.cc b/model/annotated-topology-reader.cc
index 2ca17eb..194a90c 100644
--- a/model/annotated-topology-reader.cc
+++ b/model/annotated-topology-reader.cc
@@ -101,21 +101,28 @@
   loc->SetPosition (Vector (posX, posY, 0));
 
   Names::Add (m_path, name, node);
+  m_nodes.Add (node);
 
   return node;
 }
 
 NodeContainer
+AnnotatedTopologyReader::GetNodes () const
+{
+  return m_nodes;
+}
+
+
+NodeContainer
 AnnotatedTopologyReader::Read (void)
 {
   ifstream topgen;
   topgen.open (GetFileName ().c_str ());
-  NodeContainer nodes;
         
   if ( !topgen.is_open () )
     {
       NS_LOG_ERROR ("Cannot open file " << GetFileName () << " for reading");
-      return nodes;
+      return m_nodes;
     }
 
   while (!topgen.eof ())
@@ -138,8 +145,9 @@
       double latitude, longitude;
 
       lineBuffer >> name >> city >> latitude >> longitude;
+      if (name.empty ()) continue;
+
       Ptr<Node> node = CreateNode (name, m_scale*longitude, -m_scale*latitude);
-      nodes.Add (node);
     }
 
   map<string, set<string> > processedLinks; // to eliminate duplications
@@ -185,12 +193,12 @@
       NS_LOG_DEBUG ("New link " << from << " <==> " << to << " / " << capacity << " with " << metric << " metric (" << delay << ", " << maxPackets << ")");
     }
         
-  NS_LOG_INFO ("Annotated topology created with " << nodes.GetN () << " nodes and " << LinksSize () << " links");
+  NS_LOG_INFO ("Annotated topology created with " << m_nodes.GetN () << " nodes and " << LinksSize () << " links");
   topgen.close ();
         
   ApplySettings ();
   
-  return nodes;
+  return m_nodes;
 }
     
 void
diff --git a/model/annotated-topology-reader.h b/model/annotated-topology-reader.h
index cbcd890..b9268b8 100644
--- a/model/annotated-topology-reader.h
+++ b/model/annotated-topology-reader.h
@@ -53,8 +53,14 @@
    *
    * \return the container of the nodes created (or empty container if there was an error)
    */
-  virtual
-  NodeContainer Read (void);
+  virtual NodeContainer
+  Read ();
+
+  /**
+   * \brief Get nodes read by the reader
+   */
+  NodeContainer
+  GetNodes () const;
     
   /**
    * \brief Assign IPv4 addresses to all links
@@ -92,6 +98,7 @@
     
 protected:
   std::string m_path;
+  NodeContainer m_nodes;
 
 private:
   AnnotatedTopologyReader (const AnnotatedTopologyReader&);
diff --git a/model/rocketfuel-weights-reader.cc b/model/rocketfuel-weights-reader.cc
index 448464e..f6895fa 100644
--- a/model/rocketfuel-weights-reader.cc
+++ b/model/rocketfuel-weights-reader.cc
@@ -39,8 +39,7 @@
 #include "ns3/uinteger.h"
 #include "ns3/ipv4-address.h"
 
-#include "ns3/constant-position-mobility-model.h"
-#include "ns3/random-variable.h"
+#include "ns3/mobility-model.h"
 
 #include <regex.h>
 
@@ -78,14 +77,16 @@
 NodeContainer
 RocketfuelWeightsReader::Read ()
 {
+  if (m_inputType == POSITIONS)
+    return AnnotatedTopologyReader::Read ();
+  
   ifstream topgen;
   topgen.open (GetFileName ().c_str ());
-  NodeContainer nodes;
         
   if ( !topgen.is_open () )
     {
       NS_LOG_ERROR ("Cannot open file " << GetFileName () << " for reading");
-      return nodes;
+      return m_nodes;
     }
 
   map<string, set<string> > processedLinks; // to eliminate duplications
@@ -117,14 +118,12 @@
       if (fromNode == 0)
         {
           fromNode = CreateNode (from);
-          nodes.Add (fromNode);
         }
 
       Ptr<Node> toNode   = Names::Find<Node> (m_path, to);
       if (toNode == 0)
         {
           toNode = CreateNode (to);
-          nodes.Add (toNode);
         }
 
       Link *link;
@@ -142,8 +141,8 @@
         {
         case WEIGHTS:
           {
-            double metric = boost::lexical_cast<double> (attribute);
-            link->SetAttribute ("OSPF", boost::lexical_cast<string> (metric*2));
+            uint16_t metric = boost::lexical_cast<uint16_t> (attribute);
+            link->SetAttribute ("OSPF", boost::lexical_cast<string> (metric));
             break;
           }
         case LATENCIES:
@@ -165,9 +164,9 @@
 
   if (!repeatedRun)
     {
-      NS_LOG_INFO ("Rocketfuel topology created with " << nodes.GetN () << " nodes and " << LinksSize () << " links");
+      NS_LOG_INFO ("Rocketfuel topology created with " << m_nodes.GetN () << " nodes and " << LinksSize () << " links");
     }
-  return nodes;
+  return m_nodes;
 }
 
 void
@@ -178,6 +177,23 @@
   SpringMobilityHelper::InstallSprings (LinksBegin (), LinksEnd ());
 }
 
+void
+RocketfuelWeightsReader::SavePositions (const std::string &file) const
+{
+  ofstream os (file.c_str (), ios::trunc);
+  os << "router\n";
+  
+  for (NodeContainer::Iterator node = m_nodes.Begin ();
+       node != m_nodes.End ();
+       node++)
+    {
+      std::string name = Names::FindName (*node);
+      Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel> ();
+      Vector position = mobility->GetPosition ();
+
+      os << name << "\t" << "unknown" << "\t" << -position.y << "\t" << position.x << "\n";
+    }
+}
 
 // void
 // RocketfuelWeightsReader::Cheat (NodeContainer &nodes)
diff --git a/model/rocketfuel-weights-reader.h b/model/rocketfuel-weights-reader.h
index ecf4905..cf6a784 100644
--- a/model/rocketfuel-weights-reader.h
+++ b/model/rocketfuel-weights-reader.h
@@ -64,12 +64,13 @@
   enum
     {
       WEIGHTS,
-      LATENCIES
+      LATENCIES,
+      POSITIONS
     };
 
-  // void
-  // Cheat (NodeContainer &nodes);
-
+  void
+  SavePositions (const std::string &file) const;
+  
 private:
   RocketfuelWeightsReader (const RocketfuelWeightsReader&);
   RocketfuelWeightsReader& operator= (const RocketfuelWeightsReader&);