Update simulation framework to use data files to allow arbitary simulation
authorRichard Whitehouse <github@richardwhiuk.com>
Sat, 16 Apr 2011 15:32:55 +0000 (16:32 +0100)
committerRichard Whitehouse <github@richardwhiuk.com>
Sat, 16 Apr 2011 15:32:55 +0000 (16:32 +0100)
src/simulation/simulation.cc

index 96043be12a7dfe6eaf68e27ba39026dde730fabc..0d57eaf9023eff469592792d89a6da6b9ce7d442 100644 (file)
 #include "ns3/topology-module.h"
 
 #include <iostream>
-#include <cstdlib>
-#include <ctime>
+#include <fstream>
 
 using namespace ns3;
 
 NS_LOG_COMPONENT_DEFINE ("MooseSimulation");
 
-int main (int argc, char *argv[])
-{
+void setup(LinkLayerHelper::Network& n, Topology& t, std::istream& file){
 
-  bool useMoose = true;
-  std::string tracefile = "simulation.tr";
-  long hosts = 1;
-  long size = 2;
-  std::string type = "mesh";
-  long seed = 0;
-  long link = 2;
+       uint16_t port = 9;   // Discard port (RFC 863)
 
-  seed = std::time(NULL);
+       std::string line;
 
-  CommandLine cmd;                     // Allow CommandLine args
-  cmd.AddValue("moose", "Use MOOSE instead of Ethernet? [true]", useMoose);
-  cmd.AddValue("trace", "Trace file output [simulation.tr]", tracefile);
-  cmd.AddValue("type", "Network type? [mesh]", type);
-  cmd.AddValue("size", "Network size [2]", size);
-  cmd.AddValue("hosts", "Number of hosts per switch [1]", hosts);
-  cmd.AddValue("seed", "Random seed" , seed);
-  cmd.AddValue("link", "Probability of link 1/[2]" , link);
-  cmd.Parse (argc, argv);
+       std::getline(file, line);
+       if(line != "ns-moose"){
+               throw new std::runtime_error("Invalid Network Data File");
+       }
 
-  std::srand(seed);
+       unsigned long type;
+       file >> type;
+       if(type != 2){
+               throw new std::runtime_error("Invalid Network Data File Type");
+       }
 
-  Topology t;
+       unsigned long version;
+       file >> version;
+       if(version != 1){
+               throw new std::runtime_error("Invalid Network Data File Version");
+       }
 
-  if(type == "mesh"){
-      
-       t = MeshTopologyHelper::Create(hosts, size);
+       std::map<unsigned long, bool> hosts;
 
-  } else {
+       while(file.good() && !file.eof()){
+               double time;
+               unsigned long source;
+               unsigned long destination;
+               unsigned long packets;
 
-       std::cerr << "Unknown Network Type [" << type << "]" << std::endl;
-       return 1;       
+               file >> time;
+               file >> source;
+               file >> destination;
+               file >> packets;
 
-  }
+               if(file.good()){
 
-  // Moose Helper
+                       if(source > t.hosts){
+                               throw new std::runtime_error("Invalid Source in Network Data");
+                       }
 
-  MooseHelper moose;
+                       if(destination > t.hosts){
+                               throw new std::runtime_error("Invalid Destination in Network Data");
+                       }
 
-  if(useMoose){
-       moose.SetMoose();
-  } else {
-       moose.SetEthernet();
-  }
+                       if(packets == 0){
+                               throw new std::runtime_error("Invalid number of packets in Network Data.");
+                       }
 
-  // Setup Network
+                       hosts[destination] = true;
 
-  MooseHelper::Network n = moose.Create(t);
+                       UdpClientHelper helper(n.interfaces[destination].GetAddress(0), port);
+                       helper.SetAttribute("MaxPackets", UintegerValue(packets));
+                       ApplicationContainer app = helper.Install(n.hosts.Get(source));
+                       app.Start (Seconds (time));
 
-  //
-  // Create UDP Applications to send the two packets
-  //
+               }
+       }
 
-  NS_LOG_INFO ("Create Applications.");
+       NodeContainer serverNodes;
+       std::map<unsigned long, bool>::iterator it;
+       for(it = hosts.begin(); it != hosts.end(); it ++){
+               serverNodes.Add(n.hosts.Get(it->first));
+       }
 
-  uint16_t port = 9;   // Discard port (RFC 863)
+       UdpServerHelper udpServerHelper (port);
+       ApplicationContainer udpServers = udpServerHelper.Install (serverNodes);
+       udpServers.Start (Seconds (0.0));
 
-  NodeContainer serverNodes;
+}
 
-  long i, j;
 
-  for(i = 0; i < t.hosts; ++i){
+int main (int argc, char *argv[])
+{
 
-    for(j = 0; j < t.hosts; ++j){
+try {
 
-       if(i != j){             
+       std::string csmaTraceFile;
+       std::string ipTraceFile;
+       std::string networkFile;
+       std::string dataFile;
+       std::string linkLayer = "moose";
 
-          //if((rand() % link) == 0){
+       CommandLine cmd;                        // Allow CommandLine args
+       cmd.AddValue("link", "Link Layer? (moose|ethernet) [moose]", linkLayer);
+       cmd.AddValue("csma", "CSMA Trace File", csmaTraceFile);
+       cmd.AddValue("ip", "IPv4 Trace File", ipTraceFile);
+       cmd.AddValue("network", "Network Topology File", networkFile);
+       cmd.AddValue("data", "Network Data File", dataFile);
+       cmd.Parse (argc, argv);
 
-                  UdpClientHelper udpClientHelper (n.interfaces[i].GetAddress(0), port);               // j->i
-                  udpClientHelper.SetAttribute ("MaxPackets", UintegerValue (1));
+       std::ifstream networkStream(networkFile.c_str(), std::ifstream::in);
+
+       if(networkStream.fail()){
+               std::ostringstream ss;
+               ss << "Failed to open network data file [" << networkFile << "]";
+               throw new std::runtime_error(ss.str());
+       }
 
-                  ApplicationContainer udpClientA = udpClientHelper.Install (n.hosts.Get(j));
+       NS_LOG_INFO ("Create Topology");
 
-                  udpClientA.Start (Seconds ((i*t.hosts) + j));
-                  udpClientA.Stop  (Seconds ((i*t.hosts) + j + 1));
+       Topology t(networkStream);
 
-         // }
+       // Link Layer Helper
+
+       LinkLayerHelper link;
+
+       if(link.SupportsLinkLayer(linkLayer)){
+               link.SetLinkLayer(linkLayer);
+       } else {
+               std::ostringstream ss;
+               ss << "Unsupported Link Layer Protocol [" << linkLayer << "]";
+               throw new std::runtime_error(ss.str());
        }
-     }
 
-     serverNodes.Add(n.hosts.Get(i));          // Add host i as a server.
+       NS_LOG_INFO ("Create Network");
 
-  }
+       // Setup Network
 
-  UdpServerHelper udpServerHelper (port);
-  ApplicationContainer udpServers = udpServerHelper.Install (serverNodes);
-  udpServers.Start (Seconds (0.0));
+       LinkLayerHelper::Network n = link.Create(t);
+       
+       // Create UDP Applications to send the two packets
 
-  // Tracing
+       NS_LOG_INFO ("Create Application");
 
-  NS_LOG_INFO ("Configure Tracing.");
+       std::ifstream dataStream(dataFile.c_str(), std::ifstream::in);
 
-  AsciiTraceHelper ascii;
-  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (tracefile);
-  moose.csma.EnableAsciiAll(stream);
// moose.internet.EnableAsciiIpv4All(stream);
+       if(dataStream.fail()){
+               std::ostringstream ss;
+               ss << "Failed to open network data file [" << dataFile << "]";
              throw new std::runtime_error(ss.str());
 
-  NS_LOG_INFO ("Run Simulation.");
-  Simulator::Run ();
-  Simulator::Destroy ();
-  NS_LOG_INFO ("Done.");
+       }
+
+       setup(n, t, dataStream);
+
+       // Tracing
+
+       NS_LOG_INFO ("Configure Tracing");
+
+       if(csmaTraceFile != "" && ipTraceFile != ""){
+               AsciiTraceHelper ascii;
+
+               if(csmaTraceFile != ""){
+                       Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (csmaTraceFile);
+                       link.csma.EnableAsciiAll(stream);
+               }
+
+               if (ipTraceFile != ""){
+                       Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (ipTraceFile);
+                       link.internet.EnableAsciiIpv4All(stream);
+               }
+       }
+
+
+       NS_LOG_INFO ("Run Simulation");
+       Simulator::Run ();
+
+       NS_LOG_INFO ("Destroy Simulation");
+       Simulator::Destroy ();
+
+       NS_LOG_INFO ("Done");
+
+
+} catch(std::runtime_error* e) {
+       std::cerr << e->what() << std::endl;
+       return 1;
+}
 
-  return 0;
+return 0;
 
 }