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 
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 ------------------------------------
Ptr< PacketSink > sink
Definition: wifi-tcp.cc:56
holds a vector of ns3::Application pointers.
vector< vector< double > > readCordinatesFile(std::string node_coordinates_file_name)
void printCoordinateArray(const char *description, vector< vector< double > > coord_array)
void printMatrix(const char *description, vector< vector< bool > > array)
Manage ASCII trace files for device models.
Definition: trace-helper.h:161
an Inet address class
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
Hold variables of type string.
Definition: string.h:41
NetDeviceContainer Install(NodeContainer c)
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
Mobility model for which the current position does not change once it has been set and until it is se...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:278
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
cmd
Definition: second.py:35
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we&#39;ll use to write the traced bits. ...
Build a set of PointToPointNetDevice objects.
STL namespace.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:42
uint16_t port
Definition: dsdv-manet.cc:45
Class for representing data rates.
Definition: data-rate.h:88
nodes
Definition: first.py:25
holds a vector of ns3::NetDevice pointers
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
Parse command-line arguments.
Definition: command-line.h:213
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void SetPosition(const Vector &position)
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
vector< vector< bool > > readNxNMatrix(std::string adj_mat_file_name)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Helper class used to assign positions and mobility models to nodes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
a class to store IPv4 address information on an interface
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:262
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...
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
void Add(Vector v)
Add a position to the list of positions.
Interface to network animator.
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
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...
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.