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