A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Egemen K. Cetinkaya <ekc@ittc.ku.edu>
7 * Author: Justin P. Rohrer <rohrej@ittc.ku.edu>
8 * Author: Amit Dandekar <dandekar@ittc.ku.edu>
9 *
10 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
11 * ResiliNets Research Group https://resilinets.org/
12 * Information and Telecommunication Technology Center
13 * and
14 * Department of Electrical Engineering and Computer Science
15 * The University of Kansas
16 * Lawrence, KS USA
17 *
18 * Work supported in part by NSF FIND (Future Internet Design) Program
19 * under grant CNS-0626918 (Postmodern Internet Architecture) and
20 * by NSF grant CNS-1050226 (Multilayer Network Resilience Analysis and Experimentation on GENI)
21 *
22 * This program reads an upper triangular adjacency matrix (e.g. adjacency_matrix.txt) and
23 * node coordinates file (e.g. node_coordinates.txt). The program also set-ups a
24 * wired network topology with P2P links according to the adjacency matrix with
25 * nx(n-1) CBR traffic flows, in which n is the number of nodes in the adjacency matrix.
26 */
27
28// ---------- Header Includes -------------------------------------------------
29#include "ns3/applications-module.h"
30#include "ns3/assert.h"
31#include "ns3/core-module.h"
32#include "ns3/global-route-manager.h"
33#include "ns3/internet-module.h"
34#include "ns3/ipv4-global-routing-helper.h"
35#include "ns3/mobility-module.h"
36#include "ns3/netanim-module.h"
37#include "ns3/network-module.h"
38#include "ns3/point-to-point-module.h"
39
40#include <cstdlib>
41#include <fstream>
42#include <iostream>
43#include <sstream>
44#include <string>
45#include <vector>
46
47using namespace ns3;
48
49// ---------- Prototypes ------------------------------------------------------
50
51std::vector<std::vector<bool>> readNxNMatrix(std::string adj_mat_file_name);
52std::vector<std::vector<double>> readCoordinatesFile(std::string node_coordinates_file_name);
53void printCoordinateArray(const char* description, std::vector<std::vector<double>> coord_array);
54void printMatrix(const char* description, std::vector<std::vector<bool>> array);
55
56NS_LOG_COMPONENT_DEFINE("GenericTopologyCreation");
57
58int
59main(int argc, char* argv[])
60{
61 // ---------- Simulation Variables ------------------------------------------
62
63 // Change the variables and file names only in this block!
64
65 double SimTime = 3.00;
66 double SinkStartTime = 1.0001;
67 double SinkStopTime = 2.90001;
68 double AppStartTime = 2.0001;
69 double AppStopTime = 2.80001;
70
71 std::string AppPacketRate("40Kbps");
72 Config::SetDefault("ns3::OnOffApplication::PacketSize", StringValue("1000"));
73 Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue(AppPacketRate));
74 std::string LinkRate("10Mbps");
75 std::string LinkDelay("2ms");
76 // DropTailQueue::MaxPackets affects the # of dropped packets, default value:100
77 // Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (1000));
78
79 srand((unsigned)time(nullptr)); // generate different seed each time
80
81 std::string tr_name("n-node-ppp.tr");
82 std::string pcap_name("n-node-ppp");
83 std::string flow_name("n-node-ppp.xml");
84 std::string anim_name("n-node-ppp.anim.xml");
85
86 std::string adj_mat_file_name("examples/matrix-topology/adjacency_matrix.txt");
87 std::string node_coordinates_file_name("examples/matrix-topology/node_coordinates.txt");
88
89 CommandLine cmd(__FILE__);
90 cmd.Parse(argc, argv);
91
92 // ---------- End of Simulation Variables ----------------------------------
93
94 // ---------- Read Adjacency Matrix ----------------------------------------
95
96 std::vector<std::vector<bool>> Adj_Matrix;
97 Adj_Matrix = readNxNMatrix(adj_mat_file_name);
98
99 // Optionally display 2-dimensional adjacency matrix (Adj_Matrix) array
100 // printMatrix (adj_mat_file_name.c_str (),Adj_Matrix);
101
102 // ---------- End of Read Adjacency Matrix ---------------------------------
103
104 // ---------- Read Node Coordinates File -----------------------------------
105
106 std::vector<std::vector<double>> coord_array;
107 coord_array = readCoordinatesFile(node_coordinates_file_name);
108
109 // Optionally display node coordinates file
110 // printCoordinateArray (node_coordinates_file_name.c_str (),coord_array);
111
112 int n_nodes = coord_array.size();
113 int matrixDimension = Adj_Matrix.size();
114
115 if (matrixDimension != n_nodes)
116 {
117 NS_FATAL_ERROR("The number of lines in coordinate file is: "
118 << n_nodes << " not equal to the number of nodes in adjacency matrix size "
119 << matrixDimension);
120 }
121
122 // ---------- End of Read Node Coordinates File ----------------------------
123
124 // ---------- Network Setup ------------------------------------------------
125
126 NS_LOG_INFO("Create Nodes.");
127
128 NodeContainer nodes; // Declare nodes objects
129 nodes.Create(n_nodes);
130
131 NS_LOG_INFO("Create P2P Link Attributes.");
132
134 p2p.SetDeviceAttribute("DataRate", StringValue(LinkRate));
135 p2p.SetChannelAttribute("Delay", StringValue(LinkDelay));
136
137 NS_LOG_INFO("Install Internet Stack to Nodes.");
138
141
142 NS_LOG_INFO("Assign Addresses to Nodes.");
143
144 Ipv4AddressHelper ipv4_n;
145 ipv4_n.SetBase("10.0.0.0", "255.255.255.252");
146
147 NS_LOG_INFO("Create Links Between Nodes.");
148
149 uint32_t linkCount = 0;
150
151 for (size_t i = 0; i < Adj_Matrix.size(); i++)
152 {
153 for (size_t j = 0; j < Adj_Matrix[i].size(); j++)
154 {
155 if (Adj_Matrix[i][j])
156 {
157 NodeContainer n_links = NodeContainer(nodes.Get(i), nodes.Get(j));
158 NetDeviceContainer n_devs = p2p.Install(n_links);
159 ipv4_n.Assign(n_devs);
160 ipv4_n.NewNetwork();
161 linkCount++;
162 NS_LOG_INFO("matrix element [" << i << "][" << j << "] is 1");
163 }
164 else
165 {
166 NS_LOG_INFO("matrix element [" << i << "][" << j << "] is 0");
167 }
168 }
169 }
170 NS_LOG_INFO("Number of links in the adjacency matrix is: " << linkCount);
171 NS_LOG_INFO("Number of all nodes is: " << nodes.GetN());
172
173 NS_LOG_INFO("Initialize Global Routing.");
175
176 // ---------- End of Network Set-up ----------------------------------------
177
178 // ---------- Allocate Node Positions --------------------------------------
179
180 NS_LOG_INFO("Allocate Positions to Nodes.");
181
182 MobilityHelper mobility_n;
184
185 for (size_t m = 0; m < coord_array.size(); m++)
186 {
187 positionAlloc_n->Add(Vector(coord_array[m][0], coord_array[m][1], 0));
188 Ptr<Node> n0 = nodes.Get(m);
190 if (!nLoc)
191 {
193 n0->AggregateObject(nLoc);
194 }
195 // y-coordinates are negated for correct display in NetAnim
196 // NetAnim's (0,0) reference coordinates are located on upper left corner
197 // by negating the y coordinates, we declare the reference (0,0) coordinate
198 // to the bottom left corner
199 Vector nVec(coord_array[m][0], -coord_array[m][1], 0);
200 nLoc->SetPosition(nVec);
201 }
202 mobility_n.SetPositionAllocator(positionAlloc_n);
203 mobility_n.Install(nodes);
204
205 // ---------- End of Allocate Node Positions -------------------------------
206
207 // ---------- Create n*(n-1) CBR Flows -------------------------------------
208
209 NS_LOG_INFO("Setup Packet Sinks.");
210
211 uint16_t port = 9;
212
213 for (int i = 0; i < n_nodes; i++)
214 {
215 PacketSinkHelper sink("ns3::UdpSocketFactory",
217 ApplicationContainer apps_sink =
218 sink.Install(nodes.Get(i)); // sink is installed on all nodes
219 apps_sink.Start(Seconds(SinkStartTime));
220 apps_sink.Stop(Seconds(SinkStopTime));
221 }
222
223 NS_LOG_INFO("Setup CBR Traffic Sources.");
224
225 for (int i = 0; i < n_nodes; i++)
226 {
227 for (int j = 0; j < n_nodes; j++)
228 {
229 if (i != j)
230 {
231 // We needed to generate a random number (rn) to be used to eliminate
232 // the artificial congestion caused by sending the packets at the
233 // same time. This rn is added to AppStartTime to have the sources
234 // start at different time, however they will still send at the same rate.
235
237 x->SetAttribute("Min", DoubleValue(0));
238 x->SetAttribute("Max", DoubleValue(1));
239 double rn = x->GetValue();
240 Ptr<Node> n = nodes.Get(j);
241 Ptr<Ipv4> ipv4 = n->GetObject<Ipv4>();
242 Ipv4InterfaceAddress ipv4_int_addr = ipv4->GetAddress(1, 0);
243 Ipv4Address ip_addr = ipv4_int_addr.GetLocal();
245 "ns3::UdpSocketFactory",
246 InetSocketAddress(ip_addr, port)); // traffic flows from node[i] to node[j]
247 onoff.SetConstantRate(DataRate(AppPacketRate));
249 onoff.Install(nodes.Get(i)); // traffic sources are installed on all nodes
250 apps.Start(Seconds(AppStartTime + rn));
251 apps.Stop(Seconds(AppStopTime));
252 }
253 }
254 }
255
256 // ---------- End of Create n*(n-1) CBR Flows ------------------------------
257
258 // ---------- Simulation Monitoring ----------------------------------------
259
260 NS_LOG_INFO("Configure Tracing.");
261
262 AsciiTraceHelper ascii;
263 p2p.EnableAsciiAll(ascii.CreateFileStream(tr_name));
264 // p2p.EnablePcapAll(pcap_name);
265
266 // Ptr<FlowMonitor> flowmon;
267 // FlowMonitorHelper flowmonHelper;
268 // flowmon = flowmonHelper.InstallAll();
269
270 // Configure animator with default settings
271
272 AnimationInterface anim(anim_name);
273 NS_LOG_INFO("Run Simulation.");
274
275 Simulator::Stop(Seconds(SimTime));
277 // flowmon->SerializeToXmlFile(flow_name, true, true);
279
280 // ---------- End of Simulation Monitoring ---------------------------------
281
282 return 0;
283}
284
285// ---------- Function Definitions -------------------------------------------
286
287std::vector<std::vector<bool>>
288readNxNMatrix(std::string adj_mat_file_name)
289{
290 std::ifstream adj_mat_file;
291 adj_mat_file.open(adj_mat_file_name, std::ios::in);
292 if (adj_mat_file.fail())
293 {
294 NS_FATAL_ERROR("File " << adj_mat_file_name << " not found");
295 }
296 std::vector<std::vector<bool>> array;
297 int i = 0;
298 int n_nodes = 0;
299
300 while (!adj_mat_file.eof())
301 {
302 std::string line;
303 getline(adj_mat_file, line);
304 if (line.empty())
305 {
306 NS_LOG_WARN("WARNING: Ignoring blank row in the array: " << i);
307 break;
308 }
309
310 std::istringstream iss(line);
311 bool element;
312 std::vector<bool> row;
313 int j = 0;
314
315 while (iss >> element)
316 {
317 row.push_back(element);
318 j++;
319 }
320
321 if (i == 0)
322 {
323 n_nodes = j;
324 }
325
326 if (j != n_nodes)
327 {
328 NS_LOG_ERROR("ERROR: Number of elements in line "
329 << i << ": " << j
330 << " not equal to number of elements in line 0: " << n_nodes);
331 NS_FATAL_ERROR("ERROR: The number of rows is not equal to the number of columns! in "
332 "the adjacency matrix");
333 }
334 else
335 {
336 array.push_back(row);
337 }
338 i++;
339 }
340
341 if (i != n_nodes)
342 {
343 NS_LOG_ERROR("There are " << i << " rows and " << n_nodes << " columns.");
344 NS_FATAL_ERROR("ERROR: The number of rows is not equal to the number of columns! in the "
345 "adjacency matrix");
346 }
347
348 adj_mat_file.close();
349 return array;
350}
351
352std::vector<std::vector<double>>
353readCoordinatesFile(std::string node_coordinates_file_name)
354{
355 std::ifstream node_coordinates_file;
356 node_coordinates_file.open(node_coordinates_file_name, std::ios::in);
357 if (node_coordinates_file.fail())
358 {
359 NS_FATAL_ERROR("File " << node_coordinates_file_name << " not found");
360 }
361 std::vector<std::vector<double>> coord_array;
362 int m = 0;
363
364 while (!node_coordinates_file.eof())
365 {
366 std::string line;
367 getline(node_coordinates_file, line);
368
369 if (line.empty())
370 {
371 NS_LOG_WARN("WARNING: Ignoring blank row: " << m);
372 break;
373 }
374
375 std::istringstream iss(line);
376 double coordinate;
377 std::vector<double> row;
378 int n = 0;
379 while (iss >> coordinate)
380 {
381 row.push_back(coordinate);
382 n++;
383 }
384
385 if (n != 2)
386 {
387 NS_LOG_ERROR("ERROR: Number of elements at line#"
388 << m << " is " << n
389 << " 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
403void
404printMatrix(const char* description, std::vector<std::vector<bool>> array)
405{
406 std::cout << "**** Start " << description << "********" << std::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 std::cout << array[m][n] << ' ';
412 }
413 std::cout << std::endl;
414 }
415 std::cout << "**** End " << description << "********" << std::endl;
416}
417
418void
419printCoordinateArray(const char* description, std::vector<std::vector<double>> coord_array)
420{
421 std::cout << "**** Start " << description << "********" << std::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 std::cout << coord_array[m][n] << ' ';
427 }
428 std::cout << std::endl;
429 }
430 std::cout << "**** End " << description << "********" << std::endl;
431}
432
433// ---------- 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.
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.
Mobility model for which the current position does not change once it has been set and until it is se...
Class for representing data rates.
Definition data-rate.h:78
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
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.
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:69
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.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
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.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
uint16_t port
Definition dsdv-manet.cc:33
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
AnimationInterface * anim
NodeContainer nodes
void printMatrix(const char *description, std::vector< std::vector< bool > > array)
void printCoordinateArray(const char *description, std::vector< std::vector< double > > coord_array)
std::vector< std::vector< bool > > readNxNMatrix(std::string adj_mat_file_name)
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.
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition wifi-tcp.cc:44