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
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;
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;
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
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
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
145 ipv4_n.SetBase("10.0.0.0", "255.255.255.252");
146
147 NS_LOG_INFO("Create Links Between Nodes.");
148
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 {
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
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",
218 sink.Install(nodes.Get(i)); // sink is installed on all nodes
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
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
273 NS_LOG_INFO("Run Simulation.");
274
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>>
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>>
354{
355 std::ifstream node_coordinates_file;
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;
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.
Manage ASCII trace files for device models.
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.
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.
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.
Definition ptr.h:66
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 > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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