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 * 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
58using namespace ns3;
59
60// ---------- Prototypes ------------------------------------------------------
61
62std::vector<std::vector<bool>> readNxNMatrix(std::string adj_mat_file_name);
63std::vector<std::vector<double>> readCoordinatesFile(std::string node_coordinates_file_name);
64void printCoordinateArray(const char* description, std::vector<std::vector<double>> coord_array);
65void printMatrix(const char* description, std::vector<std::vector<bool>> array);
66
67NS_LOG_COMPONENT_DEFINE("GenericTopologyCreation");
68
69int
70main(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));
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));
288 // flowmon->SerializeToXmlFile(flow_name, true, true);
290
291 // ---------- End of Simulation Monitoring ---------------------------------
292
293 return 0;
294}
295
296// ---------- Function Definitions -------------------------------------------
297
298std::vector<std::vector<bool>>
299readNxNMatrix(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
363std::vector<std::vector<double>>
364readCoordinatesFile(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
414void
415printMatrix(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
429void
430printCoordinateArray(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...
Class for representing data rates.
Definition: data-rate.h:89
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.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:37
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:894
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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.
ns cmd
Definition: second.py:40
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55