A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  // ---------- End of Simulation Variables ----------------------------------
103 
104  // ---------- Read Adjacency Matrix ----------------------------------------
105 
106  vector<vector<bool> > Adj_Matrix;
107  Adj_Matrix = readNxNMatrix (adj_mat_file_name);
108 
109  // Optionally display 2-dimensional adjacency matrix (Adj_Matrix) array
110  // printMatrix (adj_mat_file_name.c_str (),Adj_Matrix);
111 
112  // ---------- End of Read Adjacency Matrix ---------------------------------
113 
114  // ---------- Read Node Coordinates File -----------------------------------
115 
116  vector<vector<double> > coord_array;
117  coord_array = readCordinatesFile (node_coordinates_file_name);
118 
119  // Optionally display node co-ordinates file
120  // printCoordinateArray (node_coordinates_file_name.c_str (),coord_array);
121 
122  int n_nodes = coord_array.size ();
123  int matrixDimension = Adj_Matrix.size ();
124 
125  if (matrixDimension != n_nodes)
126  {
127  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);
128  }
129 
130  // ---------- End of Read Node Coordinates File ----------------------------
131 
132  // ---------- Network Setup ------------------------------------------------
133 
134  NS_LOG_INFO ("Create Nodes.");
135 
136  NodeContainer nodes; // Declare nodes objects
137  nodes.Create (n_nodes);
138 
139  NS_LOG_INFO ("Create P2P Link Attributes.");
140 
141  PointToPointHelper p2p;
142  p2p.SetDeviceAttribute ("DataRate", StringValue (LinkRate));
143  p2p.SetChannelAttribute ("Delay", StringValue (LinkDelay));
144 
145  NS_LOG_INFO ("Install Internet Stack to Nodes.");
146 
147  InternetStackHelper internet;
148  internet.Install (NodeContainer::GetGlobal ());
149 
150  NS_LOG_INFO ("Assign Addresses to Nodes.");
151 
152  Ipv4AddressHelper ipv4_n;
153  ipv4_n.SetBase ("10.0.0.0", "255.255.255.252");
154 
155  NS_LOG_INFO ("Create Links Between Nodes.");
156 
157  uint32_t linkCount = 0;
158 
159  for (size_t i = 0; i < Adj_Matrix.size (); i++)
160  {
161  for (size_t j = 0; j < Adj_Matrix[i].size (); j++)
162  {
163 
164  if (Adj_Matrix[i][j] == 1)
165  {
166  NodeContainer n_links = NodeContainer (nodes.Get (i), nodes.Get (j));
167  NetDeviceContainer n_devs = p2p.Install (n_links);
168  ipv4_n.Assign (n_devs);
169  ipv4_n.NewNetwork ();
170  linkCount++;
171  NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 1");
172  }
173  else
174  {
175  NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 0");
176  }
177  }
178  }
179  NS_LOG_INFO ("Number of links in the adjacency matrix is: " << linkCount);
180  NS_LOG_INFO ("Number of all nodes is: " << nodes.GetN ());
181 
182  NS_LOG_INFO ("Initialize Global Routing.");
183  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
184 
185  // ---------- End of Network Set-up ----------------------------------------
186 
187  // ---------- Allocate Node Positions --------------------------------------
188 
189  NS_LOG_INFO ("Allocate Positions to Nodes.");
190 
191  MobilityHelper mobility_n;
192  Ptr<ListPositionAllocator> positionAlloc_n = CreateObject<ListPositionAllocator> ();
193 
194  for (size_t m = 0; m < coord_array.size (); m++)
195  {
196  positionAlloc_n->Add (Vector (coord_array[m][0], coord_array[m][1], 0));
197  Ptr<Node> n0 = nodes.Get (m);
199  if (nLoc == 0)
200  {
201  nLoc = CreateObject<ConstantPositionMobilityModel> ();
202  n0->AggregateObject (nLoc);
203  }
204  // y-coordinates are negated for correct display in NetAnim
205  // NetAnim's (0,0) reference coordinates are located on upper left corner
206  // by negating the y coordinates, we declare the reference (0,0) coordinate
207  // to the bottom left corner
208  Vector nVec (coord_array[m][0], -coord_array[m][1], 0);
209  nLoc->SetPosition (nVec);
210 
211  }
212  mobility_n.SetPositionAllocator (positionAlloc_n);
213  mobility_n.Install (nodes);
214 
215  // ---------- End of Allocate Node Positions -------------------------------
216 
217  // ---------- Create n*(n-1) CBR Flows -------------------------------------
218 
219  NS_LOG_INFO ("Setup Packet Sinks.");
220 
221  uint16_t port = 9;
222 
223  for (int i = 0; i < n_nodes; i++)
224  {
225  PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
226  ApplicationContainer apps_sink = sink.Install (nodes.Get (i)); // sink is installed on all nodes
227  apps_sink.Start (Seconds (SinkStartTime));
228  apps_sink.Stop (Seconds (SinkStopTime));
229  }
230 
231  NS_LOG_INFO ("Setup CBR Traffic Sources.");
232 
233  for (int i = 0; i < n_nodes; i++)
234  {
235  for (int j = 0; j < n_nodes; j++)
236  {
237  if (i != j)
238  {
239 
240  // We needed to generate a random number (rn) to be used to eliminate
241  // the artificial congestion caused by sending the packets at the
242  // same time. This rn is added to AppStartTime to have the sources
243  // start at different time, however they will still send at the same rate.
244 
245  Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
246  x->SetAttribute ("Min", DoubleValue (0));
247  x->SetAttribute ("Max", DoubleValue (1));
248  double rn = x->GetValue ();
249  Ptr<Node> n = nodes.Get (j);
250  Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
251  Ipv4InterfaceAddress ipv4_int_addr = ipv4->GetAddress (1, 0);
252  Ipv4Address ip_addr = ipv4_int_addr.GetLocal ();
253  OnOffHelper onoff ("ns3::UdpSocketFactory", InetSocketAddress (ip_addr, port)); // traffic flows from node[i] to node[j]
254  onoff.SetConstantRate (DataRate (AppPacketRate));
255  ApplicationContainer apps = onoff.Install (nodes.Get (i)); // traffic sources are installed on all nodes
256  apps.Start (Seconds (AppStartTime + rn));
257  apps.Stop (Seconds (AppStopTime));
258  }
259  }
260  }
261 
262  // ---------- End of Create n*(n-1) CBR Flows ------------------------------
263 
264  // ---------- Simulation Monitoring ----------------------------------------
265 
266  NS_LOG_INFO ("Configure Tracing.");
267 
268  AsciiTraceHelper ascii;
269  p2p.EnableAsciiAll (ascii.CreateFileStream (tr_name.c_str ()));
270  // p2p.EnablePcapAll (pcap_name.c_str());
271 
272  // Ptr<FlowMonitor> flowmon;
273  // FlowMonitorHelper flowmonHelper;
274  // flowmon = flowmonHelper.InstallAll ();
275 
276  // Configure animator with default settings
277 
278  AnimationInterface anim (anim_name.c_str ());
279  NS_LOG_INFO ("Run Simulation.");
280 
281  Simulator::Stop (Seconds (SimTime));
282  Simulator::Run ();
283  // flowmon->SerializeToXmlFile (flow_name.c_str(), true, true);
284  Simulator::Destroy ();
285 
286  // ---------- End of Simulation Monitoring ---------------------------------
287 
288  return 0;
289 
290 }
291 
292 // ---------- Function Definitions -------------------------------------------
293 
294 vector<vector<bool> > readNxNMatrix (std::string adj_mat_file_name)
295 {
296  ifstream adj_mat_file;
297  adj_mat_file.open (adj_mat_file_name.c_str (), ios::in);
298  if (adj_mat_file.fail ())
299  {
300  NS_FATAL_ERROR ("File " << adj_mat_file_name.c_str () << " not found");
301  }
302  vector<vector<bool> > array;
303  int i = 0;
304  int n_nodes = 0;
305 
306  while (!adj_mat_file.eof ())
307  {
308  string line;
309  getline (adj_mat_file, line);
310  if (line == "")
311  {
312  NS_LOG_WARN ("WARNING: Ignoring blank row in the array: " << i);
313  break;
314  }
315 
316  istringstream iss (line);
317  bool element;
318  vector<bool> row;
319  int j = 0;
320 
321  while (iss >> element)
322  {
323  row.push_back (element);
324  j++;
325  }
326 
327  if (i == 0)
328  {
329  n_nodes = j;
330  }
331 
332  if (j != n_nodes )
333  {
334  NS_LOG_ERROR ("ERROR: Number of elements in line " << i << ": " << j << " not equal to number of elements in line 0: " << n_nodes);
335  NS_FATAL_ERROR ("ERROR: The number of rows is not equal to the number of columns! in the adjacency matrix");
336  }
337  else
338  {
339  array.push_back (row);
340  }
341  i++;
342  }
343 
344  if (i != n_nodes)
345  {
346  NS_LOG_ERROR ("There are " << i << " rows and " << n_nodes << " columns.");
347  NS_FATAL_ERROR ("ERROR: The number of rows is not equal to the number of columns! in the adjacency matrix");
348  }
349 
350  adj_mat_file.close ();
351  return array;
352 
353 }
354 
355 vector<vector<double> > readCordinatesFile (std::string node_coordinates_file_name)
356 {
357  ifstream node_coordinates_file;
358  node_coordinates_file.open (node_coordinates_file_name.c_str (), ios::in);
359  if (node_coordinates_file.fail ())
360  {
361  NS_FATAL_ERROR ("File " << node_coordinates_file_name.c_str () << " not found");
362  }
363  vector<vector<double> > coord_array;
364  int m = 0;
365 
366  while (!node_coordinates_file.eof ())
367  {
368  string line;
369  getline (node_coordinates_file, line);
370 
371  if (line == "")
372  {
373  NS_LOG_WARN ("WARNING: Ignoring blank row: " << m);
374  break;
375  }
376 
377  istringstream iss (line);
378  double coordinate;
379  vector<double> row;
380  int n = 0;
381  while (iss >> coordinate)
382  {
383  row.push_back (coordinate);
384  n++;
385  }
386 
387  if (n != 2)
388  {
389  NS_LOG_ERROR ("ERROR: Number of elements at line#" << m << " is " << n << " which is not equal to 2 for node coordinates file");
390  exit (1);
391  }
392 
393  else
394  {
395  coord_array.push_back (row);
396  }
397  m++;
398  }
399  node_coordinates_file.close ();
400  return coord_array;
401 
402 }
403 
404 void printMatrix (const char* description, vector<vector<bool> > array)
405 {
406  cout << "**** Start " << description << "********" << endl;
407  for (size_t m = 0; m < array.size (); m++)
408  {
409  for (size_t n = 0; n < array[m].size (); n++)
410  {
411  cout << array[m][n] << ' ';
412  }
413  cout << endl;
414  }
415  cout << "**** End " << description << "********" << endl;
416 
417 }
418 
419 void printCoordinateArray (const char* description, vector<vector<double> > coord_array)
420 {
421  cout << "**** Start " << description << "********" << endl;
422  for (size_t m = 0; m < coord_array.size (); m++)
423  {
424  for (size_t n = 0; n < coord_array[m].size (); n++)
425  {
426  cout << coord_array[m][n] << ' ';
427  }
428  cout << endl;
429  }
430  cout << "**** End " << description << "********" << endl;
431 
432 }
433 
434 // ---------- End of Function Definitions ------------------------------------
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:141
an Inet address class
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
hold variables of type string
Definition: string.h:18
NetDeviceContainer Install(NodeContainer c)
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:170
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:223
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
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. ...
Build a set of PointToPointNetDevice objects.
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
a 3d vector
Definition: vector.h:31
uint16_t port
Definition: dsdv-manet.cc:44
uint32_t GetN(void) const
Get the number of Ptr stored in this container.
tuple nodes
Definition: first.py:25
Class for representing data rates.
Definition: data-rate.h:71
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
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...
void AggregateObject(Ptr< Object > other)
Definition: object.cc:242
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:667
void SetConstantRate(DataRate dataRate, uint32_t packetSize=512)
Helper function to set a constant rate source.
keep track of a set of node pointers.
int main(int argc, char *argv[])
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
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)
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:38
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:203
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...
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
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...
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
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:193
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 Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
Hold a floating point type.
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:176
Ptr< T > GetObject(void) const
Definition: object.h:362
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.