blob: 7160dabbc191970f9f2258bc459a9d636e737f77 [file] [log] [blame]
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
Alexander Afanasyev0aa11362013-07-14 15:35:00 -07003 * Copyright (c) 2011-2013 University of California, Los Angeles
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -07004 *
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 *
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070018 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 * Ilya Moiseenko <iliamo@cs.ucla.edu>
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070020 */
21
Alexander Afanasyev0c395372014-12-20 15:54:02 -080022#include "annotated-topology-reader.hpp"
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070023
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080024#include "ns3/nstime.h"
25#include "ns3/log.h"
26#include "ns3/assert.h"
27#include "ns3/names.h"
28#include "ns3/net-device-container.h"
29#include "ns3/point-to-point-helper.h"
30#include "ns3/point-to-point-net-device.h"
31#include "ns3/internet-stack-helper.h"
32#include "ns3/ipv4-address-helper.h"
33#include "ns3/ipv4-global-routing-helper.h"
34#include "ns3/drop-tail-queue.h"
35#include "ns3/ipv4-interface.h"
36#include "ns3/ipv4.h"
37#include "ns3/string.h"
38#include "ns3/pointer.h"
39#include "ns3/uinteger.h"
40#include "ns3/ipv4-address.h"
Alexander Afanasyev0c395372014-12-20 15:54:02 -080041#include "ns3/ndn-l3-protocol.hpp"
42#include "ns3/ndn-face.hpp"
Alexander Afanasyev71029732012-11-19 23:50:52 -080043#include "ns3/random-variable.h"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070044#include "ns3/error-model.h"
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080045
46#include "ns3/constant-position-mobility-model.h"
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080047
48#include <boost/foreach.hpp>
49#include <boost/lexical_cast.hpp>
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070050#include <boost/tokenizer.hpp>
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080051
Alexander Afanasyev455e4412013-05-11 12:51:11 -070052#include <boost/graph/adjacency_list.hpp>
53#include <boost/graph/graphviz.hpp>
54
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080055#include <set>
56
Alexander Afanasyevff6e3692012-07-30 00:11:02 -070057#ifdef NS3_MPI
58#include <ns3/mpi-interface.h>
59#endif
60
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070061using namespace std;
62
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070063namespace ns3 {
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070064
65NS_LOG_COMPONENT_DEFINE ("AnnotatedTopologyReader");
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070066
Alexander Afanasyev011b8592011-12-21 14:45:27 -080067AnnotatedTopologyReader::AnnotatedTopologyReader (const std::string &path, double scale/*=1.0*/)
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080068 : m_path (path)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080069 , m_randX (0, 100.0)
70 , m_randY (0, 100.0)
Alexander Afanasyev011b8592011-12-21 14:45:27 -080071 , m_scale (scale)
Alexander Afanasyevff6e3692012-07-30 00:11:02 -070072 , m_requiredPartitions (1)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070073{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080074 NS_LOG_FUNCTION (this);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080075
Alexander Afanasyevbdc0d982011-12-16 01:15:26 -080076 SetMobilityModel ("ns3::ConstantPositionMobilityModel");
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070077}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070078
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080079void
80AnnotatedTopologyReader::SetBoundingBox (double ulx, double uly, double lrx, double lry)
81{
82 NS_LOG_FUNCTION (this << ulx << uly << lrx << lry);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070083
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080084 m_randX = UniformVariable (ulx, lrx);
85 m_randY = UniformVariable (uly, lry);
86}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080087
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080088void
89AnnotatedTopologyReader::SetMobilityModel (const std::string &model)
90{
91 NS_LOG_FUNCTION (this << model);
92 m_mobilityFactory.SetTypeId (model);
93}
94
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070095AnnotatedTopologyReader::~AnnotatedTopologyReader ()
96{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080097 NS_LOG_FUNCTION (this);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070098}
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080099
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800100Ptr<Node>
Alexander Afanasyev01945432012-07-27 16:28:10 -0700101AnnotatedTopologyReader::CreateNode (const std::string name, uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800102{
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800103 NS_LOG_FUNCTION (this << name);
104 m_requiredPartitions = std::max (m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700105
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800106 Ptr<Node> node = CreateObject<Node> (systemId);
107
108 Names::Add (m_path, name, node);
109 m_nodes.Add (node);
110
111 return node;
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800112}
113
114Ptr<Node>
Alexander Afanasyev01945432012-07-27 16:28:10 -0700115AnnotatedTopologyReader::CreateNode (const std::string name, double posX, double posY, uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800116{
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800117 NS_LOG_FUNCTION (this << name << posX << posY);
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700118 m_requiredPartitions = std::max (m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700119
Alexander Afanasyev01945432012-07-27 16:28:10 -0700120 Ptr<Node> node = CreateObject<Node> (systemId);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800121 Ptr<MobilityModel> loc = DynamicCast<MobilityModel> (m_mobilityFactory.Create ());
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800122 node->AggregateObject (loc);
123
124 loc->SetPosition (Vector (posX, posY, 0));
125
126 Names::Add (m_path, name, node);
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800127 m_nodes.Add (node);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800128
129 return node;
130}
131
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700132NodeContainer
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800133AnnotatedTopologyReader::GetNodes () const
134{
135 return m_nodes;
136}
137
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800138const std::list<TopologyReader::Link>&
Ilya Moiseenkoad9e8ab2012-01-11 19:58:34 -0800139AnnotatedTopologyReader::GetLinks () const
140{
141 return m_linksList;
142}
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800143
144NodeContainer
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700145AnnotatedTopologyReader::Read (void)
146{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800147 ifstream topgen;
148 topgen.open (GetFileName ().c_str ());
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700149
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700150 if ( !topgen.is_open () || !topgen.good () )
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700151 {
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700152 NS_FATAL_ERROR ("Cannot open file " << GetFileName () << " for reading");
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800153 return m_nodes;
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700154 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800155
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800156 while (!topgen.eof ())
157 {
158 string line;
159 getline (topgen, line);
160
161 if (line == "router") break;
162 }
163
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700164 if (topgen.eof ())
165 {
166 NS_FATAL_ERROR ("Topology file " << GetFileName () << " does not have \"router\" section");
167 return m_nodes;
168 }
169
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800170 while (!topgen.eof ())
171 {
172 string line;
173 getline (topgen,line);
174 if (line[0] == '#') continue; // comments
175 if (line=="link") break; // stop reading nodes
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700176
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800177 istringstream lineBuffer (line);
178 string name, city;
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800179 double latitude = 0, longitude = 0;
Alexander Afanasyev01945432012-07-27 16:28:10 -0700180 uint32_t systemId = 0;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800181
Alexander Afanasyev01945432012-07-27 16:28:10 -0700182 lineBuffer >> name >> city >> latitude >> longitude >> systemId;
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800183 if (name.empty ()) continue;
184
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800185 Ptr<Node> node;
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700186
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800187 if (abs(latitude) > 0.001 && abs(latitude) > 0.001)
188 node = CreateNode (name, m_scale*longitude, -m_scale*latitude, systemId);
189 else
Alexander Afanasyev71029732012-11-19 23:50:52 -0800190 {
191 UniformVariable var (0,200);
192 node = CreateNode (name, var.GetValue (), var.GetValue (), systemId);
193 // node = CreateNode (name, systemId);
194 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800195 }
196
197 map<string, set<string> > processedLinks; // to eliminate duplications
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700198
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700199 if (topgen.eof ())
200 {
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700201 NS_LOG_ERROR ("Topology file " << GetFileName () << " does not have \"link\" section");
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700202 return m_nodes;
203 }
204
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700205 // SeekToSection ("link");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800206 while (!topgen.eof ())
207 {
208 string line;
209 getline (topgen,line);
210 if (line == "") continue;
211 if (line[0] == '#') continue; // comments
212
213 // NS_LOG_DEBUG ("Input: [" << line << "]");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800214
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700215 istringstream lineBuffer (line);
216 string from, to, capacity, metric, delay, maxPackets, lossRate;
217
218 lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800219
220 if (processedLinks[to].size () != 0 &&
221 processedLinks[to].find (from) != processedLinks[to].end ())
222 {
223 continue; // duplicated link
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700224 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800225 processedLinks[from].insert (to);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700226
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800227 Ptr<Node> fromNode = Names::Find<Node> (m_path, from);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800228 NS_ASSERT_MSG (fromNode != 0, from << " node not found");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800229 Ptr<Node> toNode = Names::Find<Node> (m_path, to);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800230 NS_ASSERT_MSG (toNode != 0, to << " node not found");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800231
232 Link link (fromNode, from, toNode, to);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700233
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800234 link.SetAttribute ("DataRate", capacity);
235 link.SetAttribute ("OSPF", metric);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800236
237 if (!delay.empty ())
238 link.SetAttribute ("Delay", delay);
Alexander Afanasyev120bf312011-12-19 01:24:47 -0800239 if (!maxPackets.empty ())
240 link.SetAttribute ("MaxPackets", maxPackets);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700241
242 // Saran Added lossRate
243 if (!lossRate.empty ())
244 link.SetAttribute ("LossRate", lossRate);
245
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800246 AddLink (link);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700247 NS_LOG_DEBUG ("New link " << from << " <==> " << to << " / " << capacity << " with " << metric << " metric (" << delay << ", " << maxPackets << ", " << lossRate << ")");
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700248 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700249
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800250 NS_LOG_INFO ("Annotated topology created with " << m_nodes.GetN () << " nodes and " << LinksSize () << " links");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800251 topgen.close ();
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700252
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800253 ApplySettings ();
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700254
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800255 return m_nodes;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700256}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700257
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800258void
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800259AnnotatedTopologyReader::AssignIpv4Addresses (Ipv4Address base)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800260{
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800261 Ipv4AddressHelper address (base, Ipv4Mask ("/24"));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700262
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800263 BOOST_FOREACH (const Link &link, m_linksList)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800264 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800265 address.Assign (NetDeviceContainer (link.GetFromNetDevice (),
266 link.GetToNetDevice ()));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700267
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800268 base = Ipv4Address (base.Get () + 256);
269 address.SetBase (base, Ipv4Mask ("/24"));
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800270 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800271}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700272
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800273void
274AnnotatedTopologyReader::ApplyOspfMetric ()
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800275{
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800276 BOOST_FOREACH (const Link &link, m_linksList)
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800277 {
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800278 NS_LOG_DEBUG ("OSPF: " << link.GetAttribute ("OSPF"));
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800279 uint16_t metric = boost::lexical_cast<uint16_t> (link.GetAttribute ("OSPF"));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700280
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800281 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800282 Ptr<Ipv4> ipv4 = link.GetFromNode ()->GetObject<Ipv4> ();
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800283 if (ipv4 != 0)
284 {
285 int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetFromNetDevice ());
286 NS_ASSERT (interfaceId >= 0);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700287
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800288 ipv4->SetMetric (interfaceId,metric);
289 }
290
Alexander Afanasyevcf6dc922012-08-10 16:55:27 -0700291 Ptr<ndn::L3Protocol> ndn = link.GetFromNode ()->GetObject<ndn::L3Protocol> ();
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700292 if (ndn != 0)
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800293 {
Alexander Afanasyevcf6dc922012-08-10 16:55:27 -0700294 Ptr<ndn::Face> face = ndn->GetFaceByNetDevice (link.GetFromNetDevice ());
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800295 NS_ASSERT (face != 0);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700296
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800297 face->SetMetric (metric);
298 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800299 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700300
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800301 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800302 Ptr<Ipv4> ipv4 = link.GetToNode ()->GetObject<Ipv4> ();
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800303 if (ipv4 != 0)
304 {
305 int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetToNetDevice ());
306 NS_ASSERT (interfaceId >= 0);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800307
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800308 ipv4->SetMetric (interfaceId,metric);
309 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700310
Alexander Afanasyevcf6dc922012-08-10 16:55:27 -0700311 Ptr<ndn::L3Protocol> ndn = link.GetToNode ()->GetObject<ndn::L3Protocol> ();
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700312 if (ndn != 0)
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800313 {
Alexander Afanasyevcf6dc922012-08-10 16:55:27 -0700314 Ptr<ndn::Face> face = ndn->GetFaceByNetDevice (link.GetToNetDevice ());
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800315 NS_ASSERT (face != 0);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700316
Alexander Afanasyev8e0d2812012-01-19 22:38:14 -0800317 face->SetMetric (metric);
318 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800319 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800320 }
321}
322
323void
324AnnotatedTopologyReader::ApplySettings ()
325{
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700326#ifdef NS3_MPI
Alexander Afanasyevb1b7f5d2012-08-09 09:59:43 -0700327 if (MpiInterface::IsEnabled () &&
328 MpiInterface::GetSize () != m_requiredPartitions)
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700329 {
330 std::cerr << "MPI interface is enabled, but number of partitions (" << MpiInterface::GetSize ()
331 << ") is not equal to number of partitions in the topology (" << m_requiredPartitions << ")";
332 exit (-1);
333 }
334#endif
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700335
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800336 PointToPointHelper p2p;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800337
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800338 BOOST_FOREACH (Link &link, m_linksList)
339 {
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800340 // cout << "Link: " << Findlink.GetFromNode () << ", " << link.GetToNode () << endl;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800341 string tmp;
342
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700343 ////////////////////////////////////////////////
344 if (link.GetAttributeFailSafe ("MaxPackets", tmp))
345 {
346 NS_LOG_INFO ("MaxPackets = " + link.GetAttribute ("MaxPackets"));
347
348 try
349 {
350 uint32_t maxPackets = boost::lexical_cast<uint32_t> (link.GetAttribute ("MaxPackets"));
351
352 // compatibility mode. Only DropTailQueue is supported
353 p2p.SetQueue ("ns3::DropTailQueue",
354 "MaxPackets", UintegerValue (maxPackets));
355 }
356 catch (...)
357 {
358 typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
359 tokenizer tok (link.GetAttribute ("MaxPackets"));
360
361 tokenizer::iterator token = tok.begin ();
362 p2p.SetQueue (*token);
363
364 for (token ++; token != tok.end (); token ++)
365 {
366 boost::escaped_list_separator<char> separator ('\\', '=', '\"');
367 tokenizer attributeTok (*token, separator);
368
369 tokenizer::iterator attributeToken = attributeTok.begin ();
370
371 string attribute = *attributeToken;
372 attributeToken++;
373
374 if (attributeToken == attributeTok.end ())
375 {
376 NS_LOG_ERROR ("Queue attribute [" << *token << "] should be in form <Attribute>=<Value>");
377 continue;
378 }
379
380 string value = *attributeToken;
381
382 p2p.SetQueueAttribute (attribute, StringValue (value));
383 }
384 }
385 }
386
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800387 if (link.GetAttributeFailSafe ("DataRate", tmp))
388 {
Alexander Afanasyev8f5a9bb2011-12-18 19:49:02 -0800389 NS_LOG_INFO ("DataRate = " + link.GetAttribute("DataRate"));
Alexander Afanasyev120bf312011-12-19 01:24:47 -0800390 p2p.SetDeviceAttribute ("DataRate", StringValue (link.GetAttribute ("DataRate")));
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800391 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800392
Alexander Afanasyev120bf312011-12-19 01:24:47 -0800393 if (link.GetAttributeFailSafe ("Delay", tmp))
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800394 {
Alexander Afanasyev8f5a9bb2011-12-18 19:49:02 -0800395 NS_LOG_INFO ("Delay = " + link.GetAttribute("Delay"));
Alexander Afanasyev120bf312011-12-19 01:24:47 -0800396 p2p.SetChannelAttribute ("Delay", StringValue (link.GetAttribute ("Delay")));
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800397 }
Alexander Afanasyev120bf312011-12-19 01:24:47 -0800398
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800399 NetDeviceContainer nd = p2p.Install(link.GetFromNode (), link.GetToNode ());
400 link.SetNetDevices (nd.Get (0), nd.Get (1));
401
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700402 ////////////////////////////////////////////////
403 if (link.GetAttributeFailSafe ("LossRate", tmp))
404 {
405 NS_LOG_INFO ("LinkError = " + link.GetAttribute("LossRate"));
406
407 typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
408 tokenizer tok (link.GetAttribute("LossRate"));
409
410 tokenizer::iterator token = tok.begin ();
411 ObjectFactory factory (*token);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700412
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700413 for (token ++; token != tok.end (); token ++)
414 {
415 boost::escaped_list_separator<char> separator ('\\', '=', '\"');
416 tokenizer attributeTok (*token, separator);
417
418 tokenizer::iterator attributeToken = attributeTok.begin ();
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700419
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700420 string attribute = *attributeToken;
421 attributeToken++;
422
423 if (attributeToken == attributeTok.end ())
424 {
425 NS_LOG_ERROR ("ErrorModel attribute [" << *token << "] should be in form <Attribute>=<Value>");
426 continue;
427 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700428
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700429 string value = *attributeToken;
430
431 factory.Set (attribute, StringValue (value));
432 }
433
434 nd.Get (0)->SetAttribute ("ReceiveErrorModel", PointerValue (factory.Create<ErrorModel> ()));
435 nd.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (factory.Create<ErrorModel> ()));
436 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800437 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800438}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800439
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800440void
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700441AnnotatedTopologyReader::SaveTopology (const std::string &file)
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800442{
443 ofstream os (file.c_str (), ios::trunc);
Alexander Afanasyev71029732012-11-19 23:50:52 -0800444 os << "# any empty lines and lines starting with '#' symbol is ignored\n"
445 << "\n"
446 << "# The file should contain exactly two sections: router and link, each starting with the corresponding keyword\n"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700447 << "\n"
Alexander Afanasyev71029732012-11-19 23:50:52 -0800448 << "# router section defines topology nodes and their relative positions (e.g., to use in visualizer)\n"
449 << "router\n"
450 << "\n"
451 << "# each line in this section represents one router and should have the following data\n"
452 << "# node comment yPos xPos\n";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700453
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800454 for (NodeContainer::Iterator node = m_nodes.Begin ();
455 node != m_nodes.End ();
456 node++)
457 {
458 std::string name = Names::FindName (*node);
459 Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel> ();
460 Vector position = mobility->GetPosition ();
461
Alexander Afanasyevda021012012-06-28 14:11:46 -0700462 os << name << "\t" << "NA" << "\t" << -position.y << "\t" << position.x << "\n";
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800463 }
Alexander Afanasyev71029732012-11-19 23:50:52 -0800464
465 os << "# link section defines point-to-point links between nodes and characteristics of these links\n"
466 << "\n"
467 << "link\n"
468 << "\n"
469 << "# Each line should be in the following format (only first two are required, the rest can be omitted)\n"
470 << "# srcNode dstNode bandwidth metric delay queue\n"
471 << "# bandwidth: link bandwidth\n"
472 << "# metric: routing metric\n"
473 << "# delay: link delay\n"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700474 << "# queue: MaxPackets for transmission queue on the link (both directions)\n"
475 << "# error: comma-separated list, specifying class for ErrorModel and necessary attributes\n";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800476
477 for (std::list<Link>::const_iterator link = m_linksList.begin ();
478 link != m_linksList.end ();
479 link ++)
480 {
481 os << Names::FindName (link->GetFromNode ()) << "\t";
482 os << Names::FindName (link->GetToNode ()) << "\t";
483
484 string tmp;
485 if (link->GetAttributeFailSafe ("DataRate", tmp))
486 os << link->GetAttribute("DataRate") << "\t";
487 else
488 NS_FATAL_ERROR ("DataRate must be specified for the link");
489
490 if (link->GetAttributeFailSafe ("OSPF", tmp))
491 os << link->GetAttribute("OSPF") << "\t";
492 else
493 os << "1\t";
494
495 if (link->GetAttributeFailSafe ("Delay", tmp))
496 {
497 os << link->GetAttribute("Delay") << "\t";
498
499 if (link->GetAttributeFailSafe ("MaxPackets", tmp))
500 {
501 os << link->GetAttribute("MaxPackets") << "\t";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700502
503 if (link->GetAttributeFailSafe ("LossRate", tmp))
504 {
505 os << link->GetAttribute ("LossRate") << "\t";
506 }
Alexander Afanasyev71029732012-11-19 23:50:52 -0800507 }
508 }
509 os << "\n";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700510 }
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800511}
512
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700513
514template <class Names>
515class name_writer {
516public:
517 name_writer(Names _names) : names(_names) {}
518
519 template <class VertexOrEdge>
520 void operator()(std::ostream& out, const VertexOrEdge& v) const {
521 // out << "[label=\"" << names[v] << "\",style=filled,fillcolor=\"" << colors[v] << "\"]";
522 out << "[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
523 }
524private:
525 Names names;
526};
527
528template <class Names>
529inline name_writer<Names>
530make_name_writer(Names n) {
531 return name_writer<Names>(n);
532}
533
534
535void
536AnnotatedTopologyReader::SaveGraphviz (const std::string &file)
537{
538 typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
539
540 typedef boost::property< boost::vertex_name_t, std::string, boost::property
541 < boost::vertex_index_t, uint32_t > > nodeProperty;
542
543 typedef boost::no_property edgeProperty;
544
545 typedef boost::adjacency_list< boost::setS, boost::setS, boost::undirectedS,
546 nodeProperty, edgeProperty > Graph;
547
548 typedef map<string, Traits::vertex_descriptor> node_map_t;
549 node_map_t graphNodes;
550 Graph graph;
551
552 for (NodeContainer::Iterator node = m_nodes.Begin ();
553 node != m_nodes.End ();
554 node++)
555 {
556 std::pair<node_map_t::iterator, bool>
557 retval = graphNodes.insert (make_pair (Names::FindName (*node),
558 add_vertex (nodeProperty (Names::FindName (*node)), graph)));
559 // NS_ASSERT (ok == true);
560
561 put (boost::vertex_index, graph, retval.first->second, (*node)->GetId ());
562 }
563
564 for (std::list<Link>::const_iterator link = m_linksList.begin ();
565 link != m_linksList.end ();
566 link ++)
567 {
568 node_map_t::iterator from = graphNodes.find (Names::FindName (link->GetFromNode ()));
569 node_map_t::iterator to = graphNodes.find (Names::FindName (link->GetToNode ()));
570
571 // add_edge (node->second, otherNode->second, m_graph);
572 boost::add_edge (from->second, to->second, graph);
573 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700574
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700575 ofstream of (file.c_str ());
576 boost::property_map<Graph, boost::vertex_name_t>::type names = get (boost::vertex_name, graph);
577 write_graphviz (of, graph, make_name_writer (names));
578}
579
580
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800581}