blob: c64d823cf651d88790c8cb2094c0f358bc18933c [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
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080065NS_LOG_COMPONENT_DEFINE("AnnotatedTopologyReader");
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070066
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080067AnnotatedTopologyReader::AnnotatedTopologyReader(const std::string& path, double scale /*=1.0*/)
68 : m_path(path)
69 , m_randX(0, 100.0)
70 , m_randY(0, 100.0)
71 , m_scale(scale)
72 , m_requiredPartitions(1)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070073{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080074 NS_LOG_FUNCTION(this);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080075
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -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
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080080AnnotatedTopologyReader::SetBoundingBox(double ulx, double uly, double lrx, double lry)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080081{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082 NS_LOG_FUNCTION(this << ulx << uly << lrx << lry);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070083
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080084 m_randX = UniformVariable(ulx, lrx);
85 m_randY = UniformVariable(uly, lry);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080086}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080087
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080088void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080089AnnotatedTopologyReader::SetMobilityModel(const std::string& model)
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080090{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080091 NS_LOG_FUNCTION(this << model);
92 m_mobilityFactory.SetTypeId(model);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080093}
94
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080095AnnotatedTopologyReader::~AnnotatedTopologyReader()
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070096{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -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 Afanasyevbe55cf62014-12-20 17:51:09 -0800101AnnotatedTopologyReader::CreateNode(const std::string name, uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800102{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800103 NS_LOG_FUNCTION(this << name);
104 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700105
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800106 Ptr<Node> node = CreateObject<Node>(systemId);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800107
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800108 Names::Add(m_path, name, node);
109 m_nodes.Add(node);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800110
111 return node;
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800112}
113
114Ptr<Node>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115AnnotatedTopologyReader::CreateNode(const std::string name, double posX, double posY,
116 uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800117{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800118 NS_LOG_FUNCTION(this << name << posX << posY);
119 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700120
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800121 Ptr<Node> node = CreateObject<Node>(systemId);
122 Ptr<MobilityModel> loc = DynamicCast<MobilityModel>(m_mobilityFactory.Create());
123 node->AggregateObject(loc);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800124
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800125 loc->SetPosition(Vector(posX, posY, 0));
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800126
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800127 Names::Add(m_path, name, node);
128 m_nodes.Add(node);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800129
130 return node;
131}
132
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700133NodeContainer
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134AnnotatedTopologyReader::GetNodes() const
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800135{
136 return m_nodes;
137}
138
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800139const std::list<TopologyReader::Link>&
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800140AnnotatedTopologyReader::GetLinks() const
Ilya Moiseenkoad9e8ab2012-01-11 19:58:34 -0800141{
142 return m_linksList;
143}
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800144
145NodeContainer
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146AnnotatedTopologyReader::Read(void)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700147{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800148 ifstream topgen;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149 topgen.open(GetFileName().c_str());
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700150
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800151 if (!topgen.is_open() || !topgen.good()) {
152 NS_FATAL_ERROR("Cannot open file " << GetFileName() << " for reading");
153 return m_nodes;
154 }
155
156 while (!topgen.eof()) {
157 string line;
158 getline(topgen, line);
159
160 if (line == "router")
161 break;
162 }
163
164 if (topgen.eof()) {
165 NS_FATAL_ERROR("Topology file " << GetFileName() << " does not have \"router\" section");
166 return m_nodes;
167 }
168
169 while (!topgen.eof()) {
170 string line;
171 getline(topgen, line);
172 if (line[0] == '#')
173 continue; // comments
174 if (line == "link")
175 break; // stop reading nodes
176
177 istringstream lineBuffer(line);
178 string name, city;
179 double latitude = 0, longitude = 0;
180 uint32_t systemId = 0;
181
182 lineBuffer >> name >> city >> latitude >> longitude >> systemId;
183 if (name.empty())
184 continue;
185
186 Ptr<Node> node;
187
188 if (abs(latitude) > 0.001 && abs(latitude) > 0.001)
189 node = CreateNode(name, m_scale * longitude, -m_scale * latitude, systemId);
190 else {
191 UniformVariable var(0, 200);
192 node = CreateNode(name, var.GetValue(), var.GetValue(), systemId);
193 // node = CreateNode (name, systemId);
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700194 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800195 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800196
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197 map<string, set<string>> processedLinks; // to eliminate duplications
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800198
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800199 if (topgen.eof()) {
200 NS_LOG_ERROR("Topology file " << GetFileName() << " does not have \"link\" section");
201 return m_nodes;
202 }
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700203
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700204 // SeekToSection ("link");
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800205 while (!topgen.eof()) {
206 string line;
207 getline(topgen, line);
208 if (line == "")
209 continue;
210 if (line[0] == '#')
211 continue; // comments
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800212
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800213 // NS_LOG_DEBUG ("Input: [" << line << "]");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800214
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800215 istringstream lineBuffer(line);
216 string from, to, capacity, metric, delay, maxPackets, lossRate;
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700217
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800218 lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800219
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800220 if (processedLinks[to].size() != 0
221 && processedLinks[to].find(from) != processedLinks[to].end()) {
222 continue; // duplicated link
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700223 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800224 processedLinks[from].insert(to);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700225
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800226 Ptr<Node> fromNode = Names::Find<Node>(m_path, from);
227 NS_ASSERT_MSG(fromNode != 0, from << " node not found");
228 Ptr<Node> toNode = Names::Find<Node>(m_path, to);
229 NS_ASSERT_MSG(toNode != 0, to << " node not found");
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700230
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800231 Link link(fromNode, from, toNode, to);
232
233 link.SetAttribute("DataRate", capacity);
234 link.SetAttribute("OSPF", metric);
235
236 if (!delay.empty())
237 link.SetAttribute("Delay", delay);
238 if (!maxPackets.empty())
239 link.SetAttribute("MaxPackets", maxPackets);
240
241 // Saran Added lossRate
242 if (!lossRate.empty())
243 link.SetAttribute("LossRate", lossRate);
244
245 AddLink(link);
246 NS_LOG_DEBUG("New link " << from << " <==> " << to << " / " << capacity << " with " << metric
247 << " metric (" << delay << ", " << maxPackets << ", " << lossRate
248 << ")");
249 }
250
251 NS_LOG_INFO("Annotated topology created with " << m_nodes.GetN() << " nodes and " << LinksSize()
252 << " links");
253 topgen.close();
254
255 ApplySettings();
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700256
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800257 return m_nodes;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700258}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700259
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800260void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800261AnnotatedTopologyReader::AssignIpv4Addresses(Ipv4Address base)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800262{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800263 Ipv4AddressHelper address(base, Ipv4Mask("/24"));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700264
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800265 BOOST_FOREACH (const Link& link, m_linksList) {
266 address.Assign(NetDeviceContainer(link.GetFromNetDevice(), link.GetToNetDevice()));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700267
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800268 base = Ipv4Address(base.Get() + 256);
269 address.SetBase(base, Ipv4Mask("/24"));
270 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800271}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700272
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800273void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800274AnnotatedTopologyReader::ApplyOspfMetric()
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800275{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800276 BOOST_FOREACH (const Link& link, m_linksList) {
277 NS_LOG_DEBUG("OSPF: " << link.GetAttribute("OSPF"));
278 uint16_t metric = boost::lexical_cast<uint16_t>(link.GetAttribute("OSPF"));
279
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800280 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800281 Ptr<Ipv4> ipv4 = link.GetFromNode()->GetObject<Ipv4>();
282 if (ipv4 != 0) {
283 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetFromNetDevice());
284 NS_ASSERT(interfaceId >= 0);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700285
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800286 ipv4->SetMetric(interfaceId, metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800287 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700288
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800289 Ptr<ndn::L3Protocol> ndn = link.GetFromNode()->GetObject<ndn::L3Protocol>();
290 if (ndn != 0) {
291 Ptr<ndn::Face> face = ndn->GetFaceByNetDevice(link.GetFromNetDevice());
292 NS_ASSERT(face != 0);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800293
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800294 face->SetMetric(metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800295 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800296 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800297
298 {
299 Ptr<Ipv4> ipv4 = link.GetToNode()->GetObject<Ipv4>();
300 if (ipv4 != 0) {
301 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetToNetDevice());
302 NS_ASSERT(interfaceId >= 0);
303
304 ipv4->SetMetric(interfaceId, metric);
305 }
306
307 Ptr<ndn::L3Protocol> ndn = link.GetToNode()->GetObject<ndn::L3Protocol>();
308 if (ndn != 0) {
309 Ptr<ndn::Face> face = ndn->GetFaceByNetDevice(link.GetToNetDevice());
310 NS_ASSERT(face != 0);
311
312 face->SetMetric(metric);
313 }
314 }
315 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800316}
317
318void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800319AnnotatedTopologyReader::ApplySettings()
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800320{
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700321#ifdef NS3_MPI
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800322 if (MpiInterface::IsEnabled() && MpiInterface::GetSize() != m_requiredPartitions) {
323 std::cerr << "MPI interface is enabled, but number of partitions (" << MpiInterface::GetSize()
324 << ") is not equal to number of partitions in the topology (" << m_requiredPartitions
325 << ")";
326 exit(-1);
327 }
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700328#endif
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700329
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800330 PointToPointHelper p2p;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800331
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800332 BOOST_FOREACH (Link& link, m_linksList) {
333 // cout << "Link: " << Findlink.GetFromNode () << ", " << link.GetToNode () << endl;
334 string tmp;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800335
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800336 ////////////////////////////////////////////////
337 if (link.GetAttributeFailSafe("MaxPackets", tmp)) {
338 NS_LOG_INFO("MaxPackets = " + link.GetAttribute("MaxPackets"));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700339
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800340 try {
341 uint32_t maxPackets = boost::lexical_cast<uint32_t>(link.GetAttribute("MaxPackets"));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700342
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800343 // compatibility mode. Only DropTailQueue is supported
344 p2p.SetQueue("ns3::DropTailQueue", "MaxPackets", UintegerValue(maxPackets));
345 }
346 catch (...) {
347 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
348 tokenizer tok(link.GetAttribute("MaxPackets"));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700349
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800350 tokenizer::iterator token = tok.begin();
351 p2p.SetQueue(*token);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700352
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800353 for (token++; token != tok.end(); token++) {
354 boost::escaped_list_separator<char> separator('\\', '=', '\"');
355 tokenizer attributeTok(*token, separator);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700356
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800357 tokenizer::iterator attributeToken = attributeTok.begin();
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700358
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800359 string attribute = *attributeToken;
360 attributeToken++;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700361
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800362 if (attributeToken == attributeTok.end()) {
363 NS_LOG_ERROR("Queue attribute [" << *token
364 << "] should be in form <Attribute>=<Value>");
365 continue;
366 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700367
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800368 string value = *attributeToken;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700369
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800370 p2p.SetQueueAttribute(attribute, StringValue(value));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700371 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800372 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800373 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800374
375 if (link.GetAttributeFailSafe("DataRate", tmp)) {
376 NS_LOG_INFO("DataRate = " + link.GetAttribute("DataRate"));
377 p2p.SetDeviceAttribute("DataRate", StringValue(link.GetAttribute("DataRate")));
378 }
379
380 if (link.GetAttributeFailSafe("Delay", tmp)) {
381 NS_LOG_INFO("Delay = " + link.GetAttribute("Delay"));
382 p2p.SetChannelAttribute("Delay", StringValue(link.GetAttribute("Delay")));
383 }
384
385 NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
386 link.SetNetDevices(nd.Get(0), nd.Get(1));
387
388 ////////////////////////////////////////////////
389 if (link.GetAttributeFailSafe("LossRate", tmp)) {
390 NS_LOG_INFO("LinkError = " + link.GetAttribute("LossRate"));
391
392 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
393 tokenizer tok(link.GetAttribute("LossRate"));
394
395 tokenizer::iterator token = tok.begin();
396 ObjectFactory factory(*token);
397
398 for (token++; token != tok.end(); token++) {
399 boost::escaped_list_separator<char> separator('\\', '=', '\"');
400 tokenizer attributeTok(*token, separator);
401
402 tokenizer::iterator attributeToken = attributeTok.begin();
403
404 string attribute = *attributeToken;
405 attributeToken++;
406
407 if (attributeToken == attributeTok.end()) {
408 NS_LOG_ERROR("ErrorModel attribute [" << *token
409 << "] should be in form <Attribute>=<Value>");
410 continue;
411 }
412
413 string value = *attributeToken;
414
415 factory.Set(attribute, StringValue(value));
416 }
417
418 nd.Get(0)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
419 nd.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
420 }
421 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800422}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800423
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800424void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800425AnnotatedTopologyReader::SaveTopology(const std::string& file)
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800426{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800427 ofstream os(file.c_str(), ios::trunc);
Alexander Afanasyev71029732012-11-19 23:50:52 -0800428 os << "# any empty lines and lines starting with '#' symbol is ignored\n"
429 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800430 << "# The file should contain exactly two sections: router and link, each starting with the "
431 "corresponding keyword\n"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700432 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800433 << "# router section defines topology nodes and their relative positions (e.g., to use in "
434 "visualizer)\n"
Alexander Afanasyev71029732012-11-19 23:50:52 -0800435 << "router\n"
436 << "\n"
437 << "# each line in this section represents one router and should have the following data\n"
438 << "# node comment yPos xPos\n";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700439
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800440 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
441 std::string name = Names::FindName(*node);
442 Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel>();
443 Vector position = mobility->GetPosition();
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800444
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800445 os << name << "\t"
446 << "NA"
447 << "\t" << -position.y << "\t" << position.x << "\n";
448 }
Alexander Afanasyev71029732012-11-19 23:50:52 -0800449
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800450 os
451 << "# link section defines point-to-point links between nodes and characteristics of these "
452 "links\n"
453 << "\n"
454 << "link\n"
455 << "\n"
456 << "# Each line should be in the following format (only first two are required, the rest can "
457 "be omitted)\n"
458 << "# srcNode dstNode bandwidth metric delay queue\n"
459 << "# bandwidth: link bandwidth\n"
460 << "# metric: routing metric\n"
461 << "# delay: link delay\n"
462 << "# queue: MaxPackets for transmission queue on the link (both directions)\n"
463 << "# error: comma-separated list, specifying class for ErrorModel and necessary attributes\n";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800464
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800465 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
466 link++) {
467 os << Names::FindName(link->GetFromNode()) << "\t";
468 os << Names::FindName(link->GetToNode()) << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800469
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800470 string tmp;
471 if (link->GetAttributeFailSafe("DataRate", tmp))
472 os << link->GetAttribute("DataRate") << "\t";
473 else
474 NS_FATAL_ERROR("DataRate must be specified for the link");
Alexander Afanasyev71029732012-11-19 23:50:52 -0800475
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800476 if (link->GetAttributeFailSafe("OSPF", tmp))
477 os << link->GetAttribute("OSPF") << "\t";
478 else
479 os << "1\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800480
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800481 if (link->GetAttributeFailSafe("Delay", tmp)) {
482 os << link->GetAttribute("Delay") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800483
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800484 if (link->GetAttributeFailSafe("MaxPackets", tmp)) {
485 os << link->GetAttribute("MaxPackets") << "\t";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700486
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800487 if (link->GetAttributeFailSafe("LossRate", tmp)) {
488 os << link->GetAttribute("LossRate") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800489 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800490 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700491 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800492 os << "\n";
493 }
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800494}
495
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800496template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700497class name_writer {
498public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800499 name_writer(Names _names)
500 : names(_names)
501 {
502 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700503
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800504 template<class VertexOrEdge>
505 void
506 operator()(std::ostream& out, const VertexOrEdge& v) const
507 {
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700508 // out << "[label=\"" << names[v] << "\",style=filled,fillcolor=\"" << colors[v] << "\"]";
509 out << "[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
510 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800511
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700512private:
513 Names names;
514};
515
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800516template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700517inline name_writer<Names>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800518make_name_writer(Names n)
519{
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700520 return name_writer<Names>(n);
521}
522
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700523void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800524AnnotatedTopologyReader::SaveGraphviz(const std::string& file)
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700525{
526 typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
527
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800528 typedef boost::property<boost::vertex_name_t, std::string,
529 boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700530
531 typedef boost::no_property edgeProperty;
532
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800533 typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
534 edgeProperty> Graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700535
536 typedef map<string, Traits::vertex_descriptor> node_map_t;
537 node_map_t graphNodes;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800538 Graph graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700539
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800540 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
541 std::pair<node_map_t::iterator, bool> retval = graphNodes.insert(
542 make_pair(Names::FindName(*node), add_vertex(nodeProperty(Names::FindName(*node)), graph)));
543 // NS_ASSERT (ok == true);
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700544
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800545 put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
546 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700547
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800548 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
549 link++) {
550 node_map_t::iterator from = graphNodes.find(Names::FindName(link->GetFromNode()));
551 node_map_t::iterator to = graphNodes.find(Names::FindName(link->GetToNode()));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700552
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800553 // add_edge (node->second, otherNode->second, m_graph);
554 boost::add_edge(from->second, to->second, graph);
555 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700556
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800557 ofstream of(file.c_str());
558 boost::property_map<Graph, boost::vertex_name_t>::type names = get(boost::vertex_name, graph);
559 write_graphviz(of, graph, make_name_writer(names));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700560}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800561}