OLD | NEW |
(Empty) | |
| 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 <rohrer@ittc.ku.edu> |
| 20 * Author: Amit Dandekar <dandekar@ittc.ku.edu> |
| 21 * |
| 22 * Thanks to the students and our advisor Dr. James P.G. Sterbenz |
| 23 * in the ResiliNets group at The University of Kansas, |
| 24 * https://wiki.ittc.ku.edu/resilinets/Main_Page |
| 25 * |
| 26 * This program reads an upper triangular adjacency matrix (e.g. adjacency_matri
x.txt) and |
| 27 * node coordinates file (e.g. node_coordinates.txt). The program also set-ups a |
| 28 * wired network topology with P2P links according to the adjacency matrix with |
| 29 * nx(n-1) CBR traffic flows, in which n is the number of nodes in the adjacency
matrix. |
| 30 */ |
| 31 |
| 32 // ---------- Header Includes --------------------------------------------------
-- |
| 33 #include <iostream> |
| 34 #include <fstream> |
| 35 #include <sstream> |
| 36 #include <string> |
| 37 #include <vector> |
| 38 #include <cstdlib> |
| 39 #include <time.h> |
| 40 |
| 41 #include "ns3/core-module.h" |
| 42 #include "ns3/simulator-module.h" |
| 43 #include "ns3/node-module.h" |
| 44 #include "ns3/helper-module.h" |
| 45 #include "ns3/global-route-manager.h" |
| 46 #include "ns3/mobility-module.h" |
| 47 #include "ns3/assert.h" |
| 48 |
| 49 using namespace std; |
| 50 using namespace ns3; |
| 51 |
| 52 // ---------- Prototypes -------------------------------------------------------
-- |
| 53 |
| 54 vector<vector<bool> > readNxNMatrix (std::string adj_mat_file_name); |
| 55 vector<vector<double> > readCordinatesFile (std::string node_coordinates_file_na
me); |
| 56 void printCoordinateArray (const char* description, vector<vector<double> > coor
d_array); |
| 57 void printMatrix (const char* description, vector<vector<bool> > array); |
| 58 |
| 59 NS_LOG_COMPONENT_DEFINE ("GenericTopologyCreation"); |
| 60 |
| 61 int main (int argc, char *argv[]) |
| 62 { |
| 63 |
| 64 // ---------- Simulation Variables -------------------------------------------
---- |
| 65 |
| 66 // Change the variables and file names only in this block! |
| 67 |
| 68 double SimTime = 3.00; |
| 69 double SinkStartTime = 1.0001; |
| 70 double SinkStopTime = 2.90001; |
| 71 double AppStartTime = 2.0001; |
| 72 double AppStopTime = 2.80001; |
| 73 |
| 74 std::string AppPacketRate ("40Kbps"); |
| 75 Config::SetDefault ("ns3::OnOffApplication::PacketSize",StringValue ("1000"))
; |
| 76 Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (AppPacket
Rate)); |
| 77 std::string LinkRate ("10Mbps"); |
| 78 std::string LinkDelay ("2ms"); |
| 79 // DropTailQueue::MaxPackets affects the # of dropped packets, default value:
100 |
| 80 // Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (1000)
); |
| 81 |
| 82 srand ( (unsigned)time ( NULL ) ); // generate different seed each time |
| 83 |
| 84 std::string tr_name ("n-node-ppp.tr"); |
| 85 std::string pcap_name ("n-node-ppp"); |
| 86 std::string flow_name ("n-node-ppp.xml"); |
| 87 std::string anim_name ("n-node-ppp.anim"); |
| 88 |
| 89 std::string adj_mat_file_name ("adjacency_matrix.txt"); |
| 90 std::string node_coordinates_file_name ("node_coordinates.txt"); |
| 91 |
| 92 // ---------- End of Simulation Variables ------------------------------------
---- |
| 93 |
| 94 // ---------- Read Adjacency Matrix ------------------------------------------
---- |
| 95 |
| 96 vector<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 vector<vector<double> > coord_array; |
| 107 coord_array = readCordinatesFile (node_coordinates_file_name); |
| 108 |
| 109 // Optionally display node co-ordinates 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_LOG_ERROR ("The number of lines in coordinate file is: " << n_nodes <<
" not equal to the number of nodes in adjacency matrix size " << matrixDimension
); |
| 118 exit (1); |
| 119 } |
| 120 |
| 121 // ---------- End of Read Node Coordinates File ------------------------------
---- |
| 122 |
| 123 // ---------- Network Setup --------------------------------------------------
---- |
| 124 |
| 125 NS_LOG_INFO ("Create Nodes."); |
| 126 |
| 127 NodeContainer nodes; // Declare nodes objects |
| 128 nodes.Create (n_nodes); |
| 129 |
| 130 NS_LOG_INFO ("Create P2P Link Attributes."); |
| 131 |
| 132 PointToPointHelper p2p; |
| 133 p2p.SetDeviceAttribute ("DataRate", StringValue (LinkRate)); |
| 134 p2p.SetChannelAttribute ("Delay", StringValue (LinkDelay)); |
| 135 |
| 136 NS_LOG_INFO ("Install Internet Stack to Nodes."); |
| 137 |
| 138 InternetStackHelper internet; |
| 139 internet.Install (NodeContainer::GetGlobal ()); |
| 140 |
| 141 NS_LOG_INFO ("Assign Addresses to Nodes."); |
| 142 |
| 143 Ipv4AddressHelper ipv4_n; |
| 144 ipv4_n.SetBase ("10.0.0.0", "255.255.255.252"); |
| 145 |
| 146 NS_LOG_INFO ("Create Links Between Nodes."); |
| 147 |
| 148 uint32_t linkCount = 0; |
| 149 |
| 150 Ipv4InterfaceContainer n_ic[n_nodes][n_nodes]; // Create an array of interfa
ce containers for links |
| 151 |
| 152 for (size_t i = 0; i < Adj_Matrix.size (); i++) |
| 153 { |
| 154 for (size_t j = 0; j < Adj_Matrix[i].size (); j++) |
| 155 { |
| 156 |
| 157 if (Adj_Matrix[i][j] == 1) |
| 158 { |
| 159 NodeContainer n_links = NodeContainer (nodes.Get (i), nodes.Get (j
)); |
| 160 NetDeviceContainer n_devs = p2p.Install (n_links); |
| 161 n_ic[i][j] = ipv4_n.Assign (n_devs); |
| 162 ipv4_n.NewNetwork (); |
| 163 linkCount++; |
| 164 NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 1"); |
| 165 } |
| 166 else |
| 167 { |
| 168 NS_LOG_INFO ("matrix element [" << i << "][" << j << "] is 0"); |
| 169 } |
| 170 } |
| 171 } |
| 172 NS_LOG_INFO ("Number of links in the adjacency matrix is: " << linkCount); |
| 173 uint32_t nNodes = nodes.GetN (); |
| 174 NS_LOG_INFO ("Number of all nodes is: " << nNodes); |
| 175 |
| 176 NS_LOG_INFO ("Initialize Global Routing."); |
| 177 Ipv4GlobalRoutingHelper::PopulateRoutingTables (); |
| 178 |
| 179 // ---------- End of Network Set-up ------------------------------------------
---- |
| 180 |
| 181 // ---------- Allocate Node Positions ----------------------------------------
- |
| 182 |
| 183 NS_LOG_INFO ("Allocate Positions to Nodes."); |
| 184 |
| 185 MobilityHelper mobility_n; |
| 186 Ptr<ListPositionAllocator> positionAlloc_n = CreateObject<ListPositionAllocato
r> (); |
| 187 |
| 188 for (size_t m = 0; m < coord_array.size (); m++) |
| 189 { |
| 190 positionAlloc_n->Add (Vector (coord_array[m][0], coord_array[m][1], 0)); |
| 191 Ptr<Node> n0 = nodes.Get (m); |
| 192 Ptr<CanvasLocation> nLoc = n0->GetObject<CanvasLocation> (); |
| 193 if (nLoc == 0) |
| 194 { |
| 195 nLoc = CreateObject<CanvasLocation> (); |
| 196 n0->AggregateObject (nLoc); |
| 197 } |
| 198 // y-coordinates are negated for correct display in NetAnim |
| 199 // NetAnim's (0,0) reference coordinates are located on upper left corner |
| 200 // by negating the y coordinates, we declare the reference (0,0) coordinat
e |
| 201 // to the bottom left corner |
| 202 Vector nVec (coord_array[m][0], -coord_array[m][1], 0); |
| 203 nLoc->SetLocation (nVec); |
| 204 |
| 205 } |
| 206 mobility_n.SetPositionAllocator (positionAlloc_n); |
| 207 mobility_n.Install (nodes); |
| 208 |
| 209 // ---------- End of Allocate Node Positions ---------------------------------
- |
| 210 |
| 211 // ---------- Create n*(n-1) CBR Flows ---------------------------------------
---- |
| 212 |
| 213 NS_LOG_INFO ("Setup Packet Sinks."); |
| 214 |
| 215 uint16_t port = 9; |
| 216 |
| 217 for (int i = 0; i < n_nodes; i++) |
| 218 { |
| 219 PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Add
ress::GetAny (), port)); |
| 220 ApplicationContainer apps_sink = sink.Install (nodes.Get (i)); // sink i
s installed on all nodes |
| 221 apps_sink.Start (Seconds (SinkStartTime)); |
| 222 apps_sink.Stop (Seconds (SinkStopTime)); |
| 223 } |
| 224 |
| 225 NS_LOG_INFO ("Setup CBR Traffic Sources."); |
| 226 |
| 227 for (int i = 0; i < n_nodes; i++) |
| 228 { |
| 229 for (int j = 0; j < n_nodes; j++) |
| 230 { |
| 231 if (i != j) |
| 232 { |
| 233 |
| 234 // We needed to generate a random number (rn) to be used to elimin
ate |
| 235 // the artificial congestion caused by sending the packets at the |
| 236 // same time. This rn is added to AppStartTime to have the sources |
| 237 // start at different time, however they will still send at the sa
me rate. |
| 238 |
| 239 UniformVariable x (0,1); |
| 240 double rn = x.GetValue (); |
| 241 Ptr<Node> n = nodes.Get (j); |
| 242 Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> (); |
| 243 Ipv4InterfaceAddress ipv4_int_addr = ipv4->GetAddress (1, 0); |
| 244 Ipv4Address ip_addr = ipv4_int_addr.GetLocal (); |
| 245 OnOffHelper onoff ("ns3::UdpSocketFactory", InetSocketAddress (ip_
addr, port)); // traffic flows from node[i] to node[j] |
| 246 onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariabl
e (1))); |
| 247 onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariab
le (0))); |
| 248 ApplicationContainer apps = onoff.Install (nodes.Get (i)); // tra
ffic sources are installed on all nodes |
| 249 apps.Start (Seconds (AppStartTime + rn)); |
| 250 apps.Stop (Seconds (AppStopTime)); |
| 251 } |
| 252 } |
| 253 } |
| 254 |
| 255 // ---------- End of Create n*(n-1) CBR Flows --------------------------------
---- |
| 256 |
| 257 // ---------- Simulation Monitoring ------------------------------------------
---- |
| 258 |
| 259 NS_LOG_INFO ("Configure Tracing."); |
| 260 |
| 261 AsciiTraceHelper ascii; |
| 262 p2p.EnableAsciiAll (ascii.CreateFileStream (tr_name.c_str ())); |
| 263 // p2p.EnablePcapAll (pcap_name.c_str()); |
| 264 |
| 265 // Ptr<FlowMonitor> flowmon; |
| 266 // FlowMonitorHelper flowmonHelper; |
| 267 // flowmon = flowmonHelper.InstallAll (); |
| 268 |
| 269 // Configure animator with default settings |
| 270 |
| 271 AnimationInterface anim; |
| 272 anim.SetServerPort (9); |
| 273 anim.SetOutputFile (anim_name.c_str ()); |
| 274 anim.StartAnimation (); |
| 275 |
| 276 NS_LOG_INFO ("Run Simulation."); |
| 277 |
| 278 Simulator::Stop (Seconds (SimTime)); |
| 279 Simulator::Run (); |
| 280 // flowmon->SerializeToXmlFile (flow_name.c_str(), true, true); |
| 281 Simulator::Destroy (); |
| 282 |
| 283 // ---------- End of Simulation Monitoring -----------------------------------
---- |
| 284 |
| 285 return 0; |
| 286 |
| 287 } |
| 288 |
| 289 // ---------- Function Definitions ---------------------------------------------
-- |
| 290 |
| 291 vector<vector<bool> > readNxNMatrix (std::string adj_mat_file_name) |
| 292 { |
| 293 ifstream adj_mat_file (adj_mat_file_name.c_str ()); |
| 294 vector<vector<bool> > array; |
| 295 int i = 0; |
| 296 int n_nodes = 0; |
| 297 |
| 298 while (!adj_mat_file.eof ()) |
| 299 { |
| 300 string line; |
| 301 getline (adj_mat_file, line); |
| 302 if (line == "") |
| 303 { |
| 304 NS_LOG_WARN ("WARNING: Ignoring blank row in the array: " << i); |
| 305 break; |
| 306 } |
| 307 |
| 308 istringstream iss (line); |
| 309 bool element; |
| 310 vector<bool> row; |
| 311 int j = 0; |
| 312 |
| 313 while (iss >> element) |
| 314 { |
| 315 row.push_back (element); |
| 316 j++; |
| 317 } |
| 318 |
| 319 if (i == 0) |
| 320 { |
| 321 n_nodes = j; |
| 322 } |
| 323 |
| 324 if (j != n_nodes ) |
| 325 { |
| 326 NS_LOG_ERROR ("ERROR: Number of elements in line " << i << ": " << j <
< " not equal to number of elements in line 0: " << n_nodes); |
| 327 NS_LOG_ERROR ("ERROR: The number of rows is not equal to the number of
columns! in the adjacency matrix"); |
| 328 exit (1); |
| 329 } |
| 330 else |
| 331 { |
| 332 array.push_back (row); |
| 333 } |
| 334 i++; |
| 335 } |
| 336 |
| 337 if (i != n_nodes) |
| 338 { |
| 339 NS_LOG_ERROR ("There are " << i << " rows and " << n_nodes << " columns.")
; |
| 340 NS_LOG_ERROR ("ERROR: The number of rows is not equal to the number of col
umns! in the adjacency matrix"); |
| 341 exit (1); |
| 342 } |
| 343 |
| 344 return array; |
| 345 |
| 346 } |
| 347 |
| 348 vector<vector<double> > readCordinatesFile (std::string node_coordinates_file_na
me) |
| 349 { |
| 350 ifstream node_coordinates_file (node_coordinates_file_name.c_str ()); |
| 351 vector<vector<double> > coord_array; |
| 352 int m = 0; |
| 353 |
| 354 while (!node_coordinates_file.eof ()) |
| 355 { |
| 356 string line; |
| 357 getline (node_coordinates_file, line); |
| 358 |
| 359 if (line == "") |
| 360 { |
| 361 NS_LOG_WARN ("WARNING: Ignoring blank row: " << m); |
| 362 break; |
| 363 } |
| 364 |
| 365 istringstream iss (line); |
| 366 double coordinate; |
| 367 vector<double> row; |
| 368 int n = 0; |
| 369 while (iss >> coordinate) |
| 370 { |
| 371 row.push_back (coordinate); |
| 372 n++; |
| 373 } |
| 374 |
| 375 if (n != 2) |
| 376 { |
| 377 NS_LOG_ERROR ("ERROR: Number of elements at line#" << m << " is " <<
n << " which is not equal to 2 for node coordinates file"); |
| 378 exit (1); |
| 379 } |
| 380 |
| 381 else |
| 382 { |
| 383 coord_array.push_back (row); |
| 384 } |
| 385 m++; |
| 386 } |
| 387 |
| 388 return coord_array; |
| 389 |
| 390 } |
| 391 |
| 392 void printMatrix (const char* description, vector<vector<bool> > array) |
| 393 { |
| 394 cout << "**** Start " << description << "********" << endl; |
| 395 for (size_t m = 0; m < array.size (); m++) |
| 396 { |
| 397 for (size_t n = 0; n < array[m].size (); n++) |
| 398 { |
| 399 cout << array[m][n] << ' '; |
| 400 } |
| 401 cout << endl; |
| 402 } |
| 403 cout << "**** End " << description << "********" << endl; |
| 404 |
| 405 } |
| 406 |
| 407 void printCoordinateArray (const char* description, vector<vector<double> > coor
d_array) |
| 408 { |
| 409 cout << "**** Start " << description << "********" << endl; |
| 410 for (size_t m = 0; m < coord_array.size (); m++) |
| 411 { |
| 412 for (size_t n = 0; n < coord_array[m].size (); n++) |
| 413 { |
| 414 cout << coord_array[m][n] << ' '; |
| 415 } |
| 416 cout << endl; |
| 417 } |
| 418 cout << "**** End " << description << "********" << endl; |
| 419 |
| 420 } |
| 421 |
| 422 // ---------- End of Function Definitions --------------------------------------
-- |
OLD | NEW |