A Discrete-Event Network Simulator
API
matrix-topology.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Egemen K. Cetinkaya, Justin P. Rohrer, and Amit Dandekar
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Egemen K. Cetinkaya <ekc@ittc.ku.edu>
19  * Author: Justin P. Rohrer <rohrej@ittc.ku.edu>
20  * Author: Amit Dandekar <dandekar@ittc.ku.edu>
21  *
22  * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
23  * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
24  * Information and Telecommunication Technology Center
25  * and
26  * Department of Electrical Engineering and Computer Science
27  * The University of Kansas
28  * Lawrence, KS USA
29  *
30  * Work supported in part by NSF FIND (Future Internet Design) Program
31  * under grant CNS-0626918 (Postmodern Internet Architecture) and
32  * by NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI)
33  *
34  * This program reads an upper triangular adjacency matrix (e.g. adjacency_matrix.txt) and
35  * node coordinates file (e.g. node_coordinates.txt). The program also set-ups a
36  * wired network topology with P2P links according to the adjacency matrix with
37  * nx(n-1) CBR traffic flows, in which n is the number of nodes in the adjacency matrix.
38  */
39 
40 // ---------- Header Includes -------------------------------------------------
41 #include <iostream>
42 #include <fstream>
43 #include <sstream>
44 #include <string>
45 #include <vector>
46 #include <cstdlib>
47 
48 #include "ns3/core-module.h"
49 #include "ns3/network-module.h"
50 #include "ns3/internet-module.h"
51 #include "ns3/point-to-point-module.h"
52 #include "ns3/applications-module.h"
53 #include "ns3/global-route-manager.h"
54 #include "ns3/mobility-module.h"
55 #include "ns3/netanim-module.h"
56 #include "ns3/assert.h"
57 #include "ns3/ipv4-global-routing-helper.h"
58 
59 using namespace std;
60 using namespace ns3;
61 
62 // ---------- Prototypes ------------------------------------------------------
63 
64 vector<vector<bool> > readNxNMatrix (std::string adj_mat_file_name);
65 vector<vector<double> > readCordinatesFile (std::string node_coordinates_file_name);
66 void printCoordinateArray (const char* description, vector<vector<double> > coord_array);
67 void printMatrix (const char* description, vector<vector<bool> > array);
68 
69 NS_LOG_COMPONENT_DEFINE ("GenericTopologyCreation");
70 
71 int main (int argc, char *argv[])
72 {
73 
74  // ---------- Simulation Variables ------------------------------------------
75 
76  // Change the variables and file names only in this block!
77 
78  double SimTime = 3.00;
79  double SinkStartTime = 1.0001;
80  double SinkStopTime = 2.90001;
81  double AppStartTime = 2.0001;
82  double AppStopTime = 2.80001;
83 
84  std::string AppPacketRate ("40Kbps");
85  Config::SetDefault ("ns3::OnOffApplication::PacketSize",StringValue ("1000"));
86  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (AppPacketRate));
87  std::string LinkRate ("10Mbps");
88  std::string LinkDelay ("2ms");
89  // DropTailQueue::MaxPackets affects the # of dropped packets, default value:100
90  // Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (1000));
91 
92  srand ( (unsigned)time ( NULL ) ); // generate different seed each time
93 
94  std::string tr_name ("n-node-ppp.tr");
95  std::string pcap_name ("n-node-ppp");
96  std::string flow_name ("n-node-ppp.xml");
97  std::string anim_name ("n-node-ppp.anim.xml");
98 
99  std::string adj_mat_file_name ("examples/matrix-topology/adjacency_matrix.txt");
100  std::string node_coordinates_file_name ("examples/matrix-topology/node_coordinates.txt");
101 
102  CommandLine cmd (__FILE__);
103  cmd.Parse (argc, argv);
104 
105  // ---------- End of Simulation Variables ----------------------------------
106 
107  // ---------- Read Adjacency Matrix ----------------------------------------
108 
109  vector<vector<bool> > Adj_Matrix;
110  Adj_Matrix = readNxNMatrix (adj_mat_file_name);
111 
112  // Optionally display 2-dimensional adjacency matrix (Adj_Matrix) array
113  // printMatrix (adj_mat_file_name.c_str (),Adj_Matrix);
114 
115  // ---------- End of Read Adjacency Matrix ---------------------------------
116 
117  // ---------- Read Node Coordinates File -----------------------------------
118 
119  vector<vector<double> > coord_array;
120  coord_array = readCordinatesFile (node_coordinates_file_name);
121 
122  // Optionally display node co-ordinates file
123  // printCoordinateArray (node_coordinates_file_name.c_str (),coord_array);
124 
125  int n_nodes = coord_array.size ();
126  int matrixDimension = Adj_Matrix.size ();
127 
128  if (matrixDimension != n_nodes)
129  {
130  NS_FATAL_ERROR ("The number of lines in coordinate file is: " << n_nodes << " not equal to the number of nodes in adjacency matrix size " << matrixDimension);
131  }
132 
133  // ---------- End of Read Node Coordinates File ----------------------------
134 
135  // ---------- Network Setup ------------------------------------------------
136 
137  NS_LOG_INFO ("Create Nodes.");
138 
139  NodeContainer nodes; // Declare nodes objects
140  nodes.Create (n_nodes);
141 
142  NS_LOG_INFO ("Create P2P Link Attributes.");
143 
144  PointToPointHelper p2p;
145  p2p.SetDeviceAttribute ("DataRate", StringValue (LinkRate));
146  p2p.SetChannelAttribute ("Delay", StringValue (LinkDelay));
147 
148  NS_LOG_INFO ("Install Internet Stack to Nodes.");
149 
150  InternetStackHelper internet;
151  internet.Install (NodeContainer::GetGlobal ());
152 
153  NS_LOG_INFO ("Assign Addresses to Nodes.");
154 
155  Ipv4AddressHelper ipv4_n;
156  ipv4_n.SetBase ("10.0.0.0", "255.255.255.252");
157 
158  NS_LOG_INFO ("Create Links Between Nodes.");
159 
160  uint32_t linkCount = 0;
161 
162  for (size_t i = 0; i < Adj_Matrix.size (); i++)
163  {
164  for (size_t j = 0; j < Adj_Matrix[i].size (); j++)
165  {
166 
167  if (Adj_Matrix[i][j] == 1)
168  {
169  NodeContainer n_links = NodeContainer (nodes.Get (i), nodes.Get (j));
170  NetDeviceContainer n_devs = p2p.Install (n_links);
171  ipv4_n.Assign (n_devs);
172  ipv4_n.NewNetwork ();
173  linkCount++;
174  NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 1");
175  }
176  else
177  {
178  NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 0");
179  }
180  }
181  }
182  NS_LOG_INFO ("Number of links in the adjacency matrix is: " << linkCount);
183  NS_LOG_INFO ("Number of all nodes is: " << nodes.GetN ());
184 
185  NS_LOG_INFO ("Initialize Global Routing.");
186  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
187 
188  // ---------- End of Network Set-up ----------------------------------------
189 
190  // ---------- Allocate Node Positions --------------------------------------
191 
192  NS_LOG_INFO ("Allocate Positions to Nodes.");
193 
194  MobilityHelper mobility_n;
195  Ptr<ListPositionAllocator> positionAlloc_n = CreateObject<ListPositionAllocator> ();
196 
197  for (size_t m = 0; m < coord_array.size (); m++)
198  {
199  positionAlloc_n->Add (Vector (coord_array[m][0], coord_array[m][1], 0));
200  Ptr<Node> n0 = nodes.Get (m);
202  if (nLoc == 0)
203  {
204  nLoc = CreateObject<ConstantPositionMobilityModel> ();
205  n0->AggregateObject (nLoc);
206  }
207  // y-coordinates are negated for correct display in NetAnim
208  // NetAnim's (0,0) reference coordinates are located on upper left corner
209  // by negating the y coordinates, we declare the reference (0,0) coordinate
210  // to the bottom left corner
211  Vector nVec (coord_array[m][0], -coord_array[m][1], 0);
212  nLoc->SetPosition (nVec);
213 
214  }
215  mobility_n.SetPositionAllocator (positionAlloc_n);
216  mobility_n.Install (nodes);
217 
218  // ---------- End of Allocate Node Positions -------------------------------
219 
220  // ---------- Create n*(n-1) CBR Flows -------------------------------------
221 
222  NS_LOG_INFO ("Setup Packet Sinks.");
223 
224  uint16_t port = 9;
225 
226  for (int i = 0; i < n_nodes; i++)
227  {
228  PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
229  ApplicationContainer apps_sink = sink.Install (nodes.Get (i)); // sink is installed on all nodes
230  apps_sink.Start (Seconds (SinkStartTime));
231  apps_sink.Stop (Seconds (SinkStopTime));
232  }
233 
234  NS_LOG_INFO ("Setup CBR Traffic Sources.");
235 
236  for (int i = 0; i < n_nodes; i++)
237  {
238  for (int j = 0; j < n_nodes; j++)
239  {
240  if (i != j)
241  {
242 
243  // We needed to generate a random number (rn) to be used to eliminate
244  // the artificial congestion caused by sending the packets at the
245  // same time. This rn is added to AppStartTime to have the sources
246  // start at different time, however they will still send at the same rate.
247 
248  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
249  x->SetAttribute ("Min", DoubleValue (0));
250  x->SetAttribute ("Max", DoubleValue (1));
251  double rn = x->GetValue ();
252  Ptr<Node> n = nodes.Get (j);
253  Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
254  Ipv4InterfaceAddress ipv4_int_addr = ipv4->GetAddress (1, 0);
255  Ipv4Address ip_addr = ipv4_int_addr.GetLocal ();
256  OnOffHelper onoff ("ns3::UdpSocketFactory", InetSocketAddress (ip_addr, port)); // traffic flows from node[i] to node[j]
257  onoff.SetConstantRate (DataRate (AppPacketRate));
258  ApplicationContainer apps = onoff.Install (nodes.Get (i)); // traffic sources are installed on all nodes
259  apps.Start (Seconds (AppStartTime + rn));
260  apps.Stop (Seconds (AppStopTime));
261  }
262  }
263  }
264 
265  // ---------- End of Create n*(n-1) CBR Flows ------------------------------
266 
267  // ---------- Simulation Monitoring ----------------------------------------
268 
269  NS_LOG_INFO ("Configure Tracing.");
270 
271  AsciiTraceHelper ascii;
272  p2p.EnableAsciiAll (ascii.CreateFileStream (tr_name.c_str ()));
273  // p2p.EnablePcapAll (pcap_name.c_str());
274 
275  // Ptr<FlowMonitor> flowmon;
276  // FlowMonitorHelper flowmonHelper;
277  // flowmon = flowmonHelper.InstallAll ();
278 
279  // Configure animator with default settings
280 
281  AnimationInterface anim (anim_name.c_str ());
282  NS_LOG_INFO ("Run Simulation.");
283 
284  Simulator::Stop (Seconds (SimTime));
285  Simulator::Run ();
286  // flowmon->SerializeToXmlFile (flow_name.c_str(), true, true);
287  Simulator::Destroy ();
288 
289  // ---------- End of Simulation Monitoring ---------------------------------
290 
291  return 0;
292 
293 }
294 
295 // ---------- Function Definitions -------------------------------------------
296 
297 vector<vector<bool> > readNxNMatrix (std::string adj_mat_file_name)
298 {
299  ifstream adj_mat_file;
300  adj_mat_file.open (adj_mat_file_name.c_str (), ios::in);
301  if (adj_mat_file.fail ())
302  {
303  NS_FATAL_ERROR ("File " << adj_mat_file_name.c_str () << " not found");
304  }
305  vector<vector<bool> > array;
306  int i = 0;
307  int n_nodes = 0;
308 
309  while (!adj_mat_file.eof ())
310  {
311  string line;
312  getline (adj_mat_file, line);
313  if (line == "")
314  {
315  NS_LOG_WARN ("WARNING: Ignoring blank row in the array: " << i);
316  break;
317  }
318 
319  istringstream iss (line);
320  bool element;
321  vector<bool> row;
322  int j = 0;
323 
324  while (iss >> element)
325  {
326  row.push_back (element);
327  j++;
328  }
329 
330  if (i == 0)
331  {
332  n_nodes = j;
333  }
334 
335  if (j != n_nodes )
336  {
337  NS_LOG_ERROR ("ERROR: Number of elements in line " << i << ": " << j << " not equal to number of elements in line 0: " << n_nodes);
338  NS_FATAL_ERROR ("ERROR: The number of rows is not equal to the number of columns! in the adjacency matrix");
339  }
340  else
341  {
342  array.push_back (row);
343  }
344  i++;
345  }
346 
347  if (i != n_nodes)
348  {
349  NS_LOG_ERROR ("There are " << i << " rows and " << n_nodes << " columns.");
350  NS_FATAL_ERROR ("ERROR: The number of rows is not equal to the number of columns! in the adjacency matrix");
351  }
352 
353  adj_mat_file.close ();
354  return array;
355 
356 }
357 
358 vector<vector<double> > readCordinatesFile (std::string node_coordinates_file_name)
359 {
360  ifstream node_coordinates_file;
361  node_coordinates_file.open (node_coordinates_file_name.c_str (), ios::in);
362  if (node_coordinates_file.fail ())
363  {
364  NS_FATAL_ERROR ("File " << node_coordinates_file_name.c_str () << " not found");
365  }
366  vector<vector<double> > coord_array;
367  int m = 0;
368 
369  while (!node_coordinates_file.eof ())
370  {
371  string line;
372  getline (node_coordinates_file, line);
373 
374  if (line == "")
375  {
376  NS_LOG_WARN ("WARNING: Ignoring blank row: " << m);
377  break;
378  }
379 
380  istringstream iss (line);
381  double coordinate;
382  vector<double> row;
383  int n = 0;
384  while (iss >> coordinate)
385  {
386  row.push_back (coordinate);
387  n++;
388  }
389 
390  if (n != 2)
391  {
392  NS_LOG_ERROR ("ERROR: Number of elements at line#" << m << " is " << n << " which is not equal to 2 for node coordinates file");
393  exit (1);
394  }
395 
396  else
397  {
398  coord_array.push_back (row);
399  }
400  m++;
401  }
402  node_coordinates_file.close ();
403  return coord_array;
404 
405 }
406 
407 void printMatrix (const char* description, vector<vector<bool> > array)
408 {
409  cout << "**** Start " << description << "********" << endl;
410  for (size_t m = 0; m < array.size (); m++)
411  {
412  for (size_t n = 0; n < array[m].size (); n++)
413  {
414  cout << array[m][n] << ' ';
415  }
416  cout << endl;
417  }
418  cout << "**** End " << description << "********" << endl;
419 
420 }
421 
422 void printCoordinateArray (const char* description, vector<vector<double> > coord_array)
423 {
424  cout << "**** Start " << description << "********" << endl;
425  for (size_t m = 0; m < coord_array.size (); m++)
426  {
427  for (size_t n = 0; n < coord_array[m].size (); n++)
428  {
429  cout << coord_array[m][n] << ' ';
430  }
431  cout << endl;
432  }
433  cout << "**** End " << description << "********" << endl;
434 
435 }
436 
437 // ---------- End of Function Definitions ------------------------------------
ns3::NetDeviceContainer
holds a vector of ns3::NetDevice pointers
Definition: net-device-container.h:42
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::InetSocketAddress
an Inet address class
Definition: inet-socket-address.h:41
ns3::CommandLine
Parse command-line arguments.
Definition: command-line.h:228
ns3::AsciiTraceHelperForDevice::EnableAsciiAll
void EnableAsciiAll(std::string prefix)
Enable ascii trace output on each device (which is of the appropriate type) in the set of all nodes c...
Definition: trace-helper.cc:586
ns3::ListPositionAllocator::Add
void Add(Vector v)
Add a position to the list of positions.
Definition: position-allocator.cc:70
ns3::Ipv4AddressHelper::NewNetwork
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
Definition: ipv4-address-helper.cc:126
ns3::ConstantPositionMobilityModel
Mobility model for which the current position does not change once it has been set and until it is se...
Definition: constant-position-mobility-model.h:33
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::ApplicationContainer::Stop
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Definition: application-container.cc:107
ns3::Ipv4AddressHelper
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Definition: ipv4-address-helper.h:48
ns3::MobilityHelper::Install
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
Definition: mobility-helper.cc:130
ns3::PointToPointHelper::SetDeviceAttribute
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
Definition: point-to-point-helper.cc:69
ns3::PointToPointHelper::SetChannelAttribute
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
Definition: point-to-point-helper.cc:75
ns3::Object::GetObject
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
ns3::MobilityModel::SetPosition
void SetPosition(const Vector &position)
Definition: mobility-model.cc:88
NS_LOG_WARN
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
ns3::PointToPointHelper::Install
NetDeviceContainer Install(NodeContainer c)
Definition: point-to-point-helper.cc:222
ns3::Ipv4Address
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
ns3::AnimationInterface
Interface to network animator.
Definition: animation-interface.h:76
ns3::DoubleValue
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
first.nodes
nodes
Definition: first.py:32
ns3::Ipv4AddressHelper::SetBase
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Definition: ipv4-address-helper.cc:64
ns3::Ipv4
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
NS_FATAL_ERROR
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
ns3::DataRate
Class for representing data rates.
Definition: data-rate.h:89
ns3::MobilityHelper::SetPositionAllocator
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
Definition: mobility-helper.cc:47
ns3::Ipv4InterfaceAddress
a class to store IPv4 address information on an interface
Definition: ipv4-interface-address.h:44
printCoordinateArray
void printCoordinateArray(const char *description, vector< vector< double > > coord_array)
Definition: matrix-topology.cc:422
ns3::InternetStackHelper::Install
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Definition: internet-stack-helper.cc:366
ns3::OnOffHelper
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:43
NS_LOG_INFO
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
ns3::AsciiTraceHelper::CreateFileStream
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
Definition: trace-helper.cc:191
ns3::Object::AggregateObject
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
readNxNMatrix
vector< vector< bool > > readNxNMatrix(std::string adj_mat_file_name)
Definition: matrix-topology.cc:297
second.cmd
cmd
Definition: second.py:35
printMatrix
void printMatrix(const char *description, vector< vector< bool > > array)
Definition: matrix-topology.cc:407
sink
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:56
ns3::StringValue
Hold variables of type string.
Definition: string.h:41
ns3::PacketSinkHelper
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Definition: packet-sink-helper.h:36
NS_LOG_ERROR
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
ns3::AsciiTraceHelper
Manage ASCII trace files for device models.
Definition: trace-helper.h:163
ns3::Ipv4::GetAddress
virtual Ipv4InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
Because addresses can be removed, the addressIndex is not guaranteed to be static across calls to thi...
ns3::ApplicationContainer::Start
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
Definition: application-container.cc:87
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
ns3::Ipv4AddressHelper::Assign
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Definition: ipv4-address-helper.cc:135
ns3::ApplicationContainer
holds a vector of ns3::Application pointers.
Definition: application-container.h:43
sample-rng-plot.x
list x
Definition: sample-rng-plot.py:34
ns3::PointToPointHelper
Build a set of PointToPointNetDevice objects.
Definition: point-to-point-helper.h:45
ns3::NodeContainer
keep track of a set of node pointers.
Definition: node-container.h:39
ns3::Config::SetDefault
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
ns3::InternetStackHelper
aggregate IP/TCP/UDP functionality to existing Nodes.
Definition: internet-stack-helper.h:88
ns3::MobilityHelper
Helper class used to assign positions and mobility models to nodes.
Definition: mobility-helper.h:43
sample-rng-plot.n
n
Definition: sample-rng-plot.py:37
readCordinatesFile
vector< vector< double > > readCordinatesFile(std::string node_coordinates_file_name)
Definition: matrix-topology.cc:358
port
uint16_t port
Definition: dsdv-manet.cc:45