blob: 2874616152d23059fddccfaa807ada8d7e94c15c [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -07004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -07007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20// Based on the code by Hajime Tazaki <tazaki@sfc.wide.ad.jp>
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070021
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 Afanasyevda2f23a2013-04-14 22:52:50 -070041#include "ns3/error-model.h"
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080042#include "ns3/constant-position-mobility-model.h"
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070043#include "ns3/double.h"
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080044
Alexander Afanasyevdca091a2015-01-01 20:51:27 -080045#include "model/ndn-l3-protocol.hpp"
46#include "model/ndn-net-device-face.hpp"
47
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080048#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)
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070069 , m_randX(CreateObject<UniformRandomVariable>())
70 , m_randY(CreateObject<UniformRandomVariable>())
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080071 , 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 Afanasyevd6453cd2015-08-20 21:45:36 -070076 m_randX->SetAttribute("Min", DoubleValue(0));
77 m_randX->SetAttribute("Max", DoubleValue(100.0));
78
79 m_randY->SetAttribute("Min", DoubleValue(0));
80 m_randY->SetAttribute("Max", DoubleValue(100.0));
81
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082 SetMobilityModel("ns3::ConstantPositionMobilityModel");
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070083}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070084
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080085void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080086AnnotatedTopologyReader::SetBoundingBox(double ulx, double uly, double lrx, double lry)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080087{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080088 NS_LOG_FUNCTION(this << ulx << uly << lrx << lry);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070089
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070090 m_randX->SetAttribute("Min", DoubleValue(ulx));
91 m_randX->SetAttribute("Max", DoubleValue(lrx));
92
93 m_randY->SetAttribute("Min", DoubleValue(uly));
94 m_randY->SetAttribute("Max", DoubleValue(lry));
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080095}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080096
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080097void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098AnnotatedTopologyReader::SetMobilityModel(const std::string& model)
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080099{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 NS_LOG_FUNCTION(this << model);
101 m_mobilityFactory.SetTypeId(model);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800102}
103
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800104AnnotatedTopologyReader::~AnnotatedTopologyReader()
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700105{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800106 NS_LOG_FUNCTION(this);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700107}
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800108
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800109Ptr<Node>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110AnnotatedTopologyReader::CreateNode(const std::string name, uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800111{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800112 NS_LOG_FUNCTION(this << name);
113 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700114
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115 Ptr<Node> node = CreateObject<Node>(systemId);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800116
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800117 Names::Add(m_path, name, node);
118 m_nodes.Add(node);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800119
120 return node;
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800121}
122
123Ptr<Node>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800124AnnotatedTopologyReader::CreateNode(const std::string name, double posX, double posY,
125 uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800126{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800127 NS_LOG_FUNCTION(this << name << posX << posY);
128 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700129
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130 Ptr<Node> node = CreateObject<Node>(systemId);
131 Ptr<MobilityModel> loc = DynamicCast<MobilityModel>(m_mobilityFactory.Create());
132 node->AggregateObject(loc);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800133
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134 loc->SetPosition(Vector(posX, posY, 0));
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800135
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 Names::Add(m_path, name, node);
137 m_nodes.Add(node);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800138
139 return node;
140}
141
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700142NodeContainer
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800143AnnotatedTopologyReader::GetNodes() const
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800144{
145 return m_nodes;
146}
147
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800148const std::list<TopologyReader::Link>&
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149AnnotatedTopologyReader::GetLinks() const
Ilya Moiseenkoad9e8ab2012-01-11 19:58:34 -0800150{
151 return m_linksList;
152}
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800153
154NodeContainer
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800155AnnotatedTopologyReader::Read(void)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700156{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800157 ifstream topgen;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800158 topgen.open(GetFileName().c_str());
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700159
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 if (!topgen.is_open() || !topgen.good()) {
161 NS_FATAL_ERROR("Cannot open file " << GetFileName() << " for reading");
162 return m_nodes;
163 }
164
165 while (!topgen.eof()) {
166 string line;
167 getline(topgen, line);
168
169 if (line == "router")
170 break;
171 }
172
173 if (topgen.eof()) {
174 NS_FATAL_ERROR("Topology file " << GetFileName() << " does not have \"router\" section");
175 return m_nodes;
176 }
177
178 while (!topgen.eof()) {
179 string line;
180 getline(topgen, line);
181 if (line[0] == '#')
182 continue; // comments
183 if (line == "link")
184 break; // stop reading nodes
185
186 istringstream lineBuffer(line);
187 string name, city;
188 double latitude = 0, longitude = 0;
189 uint32_t systemId = 0;
190
191 lineBuffer >> name >> city >> latitude >> longitude >> systemId;
192 if (name.empty())
193 continue;
194
195 Ptr<Node> node;
196
197 if (abs(latitude) > 0.001 && abs(latitude) > 0.001)
198 node = CreateNode(name, m_scale * longitude, -m_scale * latitude, systemId);
199 else {
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700200 Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
201 node = CreateNode(name, var->GetValue(0, 200), var->GetValue(0, 200), systemId);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800202 // node = CreateNode (name, systemId);
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700203 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800204 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800205
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800206 map<string, set<string>> processedLinks; // to eliminate duplications
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800207
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800208 if (topgen.eof()) {
209 NS_LOG_ERROR("Topology file " << GetFileName() << " does not have \"link\" section");
210 return m_nodes;
211 }
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700212
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700213 // SeekToSection ("link");
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 while (!topgen.eof()) {
215 string line;
216 getline(topgen, line);
217 if (line == "")
218 continue;
219 if (line[0] == '#')
220 continue; // comments
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800221
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800222 // NS_LOG_DEBUG ("Input: [" << line << "]");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800223
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800224 istringstream lineBuffer(line);
225 string from, to, capacity, metric, delay, maxPackets, lossRate;
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700226
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800227 lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800228
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800229 if (processedLinks[to].size() != 0
230 && processedLinks[to].find(from) != processedLinks[to].end()) {
231 continue; // duplicated link
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700232 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800233 processedLinks[from].insert(to);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700234
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800235 Ptr<Node> fromNode = Names::Find<Node>(m_path, from);
236 NS_ASSERT_MSG(fromNode != 0, from << " node not found");
237 Ptr<Node> toNode = Names::Find<Node>(m_path, to);
238 NS_ASSERT_MSG(toNode != 0, to << " node not found");
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700239
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800240 Link link(fromNode, from, toNode, to);
241
242 link.SetAttribute("DataRate", capacity);
243 link.SetAttribute("OSPF", metric);
244
245 if (!delay.empty())
246 link.SetAttribute("Delay", delay);
247 if (!maxPackets.empty())
248 link.SetAttribute("MaxPackets", maxPackets);
249
250 // Saran Added lossRate
251 if (!lossRate.empty())
252 link.SetAttribute("LossRate", lossRate);
253
254 AddLink(link);
255 NS_LOG_DEBUG("New link " << from << " <==> " << to << " / " << capacity << " with " << metric
256 << " metric (" << delay << ", " << maxPackets << ", " << lossRate
257 << ")");
258 }
259
260 NS_LOG_INFO("Annotated topology created with " << m_nodes.GetN() << " nodes and " << LinksSize()
261 << " links");
262 topgen.close();
263
264 ApplySettings();
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700265
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800266 return m_nodes;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700267}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700268
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800269void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800270AnnotatedTopologyReader::AssignIpv4Addresses(Ipv4Address base)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800271{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800272 Ipv4AddressHelper address(base, Ipv4Mask("/24"));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700273
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800274 BOOST_FOREACH (const Link& link, m_linksList) {
275 address.Assign(NetDeviceContainer(link.GetFromNetDevice(), link.GetToNetDevice()));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700276
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800277 base = Ipv4Address(base.Get() + 256);
278 address.SetBase(base, Ipv4Mask("/24"));
279 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800280}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700281
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800282void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800283AnnotatedTopologyReader::ApplyOspfMetric()
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800284{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800285 BOOST_FOREACH (const Link& link, m_linksList) {
286 NS_LOG_DEBUG("OSPF: " << link.GetAttribute("OSPF"));
287 uint16_t metric = boost::lexical_cast<uint16_t>(link.GetAttribute("OSPF"));
288
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800289 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800290 Ptr<Ipv4> ipv4 = link.GetFromNode()->GetObject<Ipv4>();
291 if (ipv4 != 0) {
292 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetFromNetDevice());
293 NS_ASSERT(interfaceId >= 0);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700294
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800295 ipv4->SetMetric(interfaceId, metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800296 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700297
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800298 Ptr<ndn::L3Protocol> ndn = link.GetFromNode()->GetObject<ndn::L3Protocol>();
299 if (ndn != 0) {
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800300 shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetFromNetDevice());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800301 NS_ASSERT(face != 0);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800302
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800303 face->setMetric(metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800304 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800305 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800306
307 {
308 Ptr<Ipv4> ipv4 = link.GetToNode()->GetObject<Ipv4>();
309 if (ipv4 != 0) {
310 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetToNetDevice());
311 NS_ASSERT(interfaceId >= 0);
312
313 ipv4->SetMetric(interfaceId, metric);
314 }
315
316 Ptr<ndn::L3Protocol> ndn = link.GetToNode()->GetObject<ndn::L3Protocol>();
317 if (ndn != 0) {
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800318 shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetToNetDevice());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800319 NS_ASSERT(face != 0);
320
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800321 face->setMetric(metric);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800322 }
323 }
324 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800325}
326
327void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800328AnnotatedTopologyReader::ApplySettings()
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800329{
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700330#ifdef NS3_MPI
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800331 if (MpiInterface::IsEnabled() && MpiInterface::GetSize() != m_requiredPartitions) {
332 std::cerr << "MPI interface is enabled, but number of partitions (" << MpiInterface::GetSize()
333 << ") is not equal to number of partitions in the topology (" << m_requiredPartitions
334 << ")";
335 exit(-1);
336 }
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700337#endif
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700338
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800339 PointToPointHelper p2p;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800340
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800341 BOOST_FOREACH (Link& link, m_linksList) {
342 // cout << "Link: " << Findlink.GetFromNode () << ", " << link.GetToNode () << endl;
343 string tmp;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800344
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800345 ////////////////////////////////////////////////
346 if (link.GetAttributeFailSafe("MaxPackets", tmp)) {
347 NS_LOG_INFO("MaxPackets = " + link.GetAttribute("MaxPackets"));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700348
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800349 try {
350 uint32_t maxPackets = boost::lexical_cast<uint32_t>(link.GetAttribute("MaxPackets"));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700351
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800352 // compatibility mode. Only DropTailQueue is supported
353 p2p.SetQueue("ns3::DropTailQueue", "MaxPackets", UintegerValue(maxPackets));
354 }
355 catch (...) {
356 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
Alexander Afanasyev66ae18b2015-01-06 18:30:39 -0800357 std::string value = link.GetAttribute("MaxPackets");
358 tokenizer tok(value);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700359
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800360 tokenizer::iterator token = tok.begin();
361 p2p.SetQueue(*token);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700362
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800363 for (token++; token != tok.end(); token++) {
364 boost::escaped_list_separator<char> separator('\\', '=', '\"');
365 tokenizer attributeTok(*token, separator);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700366
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800367 tokenizer::iterator attributeToken = attributeTok.begin();
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700368
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800369 string attribute = *attributeToken;
370 attributeToken++;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700371
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800372 if (attributeToken == attributeTok.end()) {
373 NS_LOG_ERROR("Queue attribute [" << *token
374 << "] should be in form <Attribute>=<Value>");
375 continue;
376 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700377
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800378 string value = *attributeToken;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700379
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800380 p2p.SetQueueAttribute(attribute, StringValue(value));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700381 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800382 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800383 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800384
385 if (link.GetAttributeFailSafe("DataRate", tmp)) {
386 NS_LOG_INFO("DataRate = " + link.GetAttribute("DataRate"));
387 p2p.SetDeviceAttribute("DataRate", StringValue(link.GetAttribute("DataRate")));
388 }
389
390 if (link.GetAttributeFailSafe("Delay", tmp)) {
391 NS_LOG_INFO("Delay = " + link.GetAttribute("Delay"));
392 p2p.SetChannelAttribute("Delay", StringValue(link.GetAttribute("Delay")));
393 }
394
395 NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
396 link.SetNetDevices(nd.Get(0), nd.Get(1));
397
398 ////////////////////////////////////////////////
399 if (link.GetAttributeFailSafe("LossRate", tmp)) {
400 NS_LOG_INFO("LinkError = " + link.GetAttribute("LossRate"));
401
402 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
Alexander Afanasyev66ae18b2015-01-06 18:30:39 -0800403 std::string value = link.GetAttribute("LossRate");
404 tokenizer tok(value);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800405
406 tokenizer::iterator token = tok.begin();
407 ObjectFactory factory(*token);
408
409 for (token++; token != tok.end(); token++) {
410 boost::escaped_list_separator<char> separator('\\', '=', '\"');
411 tokenizer attributeTok(*token, separator);
412
413 tokenizer::iterator attributeToken = attributeTok.begin();
414
415 string attribute = *attributeToken;
416 attributeToken++;
417
418 if (attributeToken == attributeTok.end()) {
419 NS_LOG_ERROR("ErrorModel attribute [" << *token
420 << "] should be in form <Attribute>=<Value>");
421 continue;
422 }
423
424 string value = *attributeToken;
425
426 factory.Set(attribute, StringValue(value));
427 }
428
429 nd.Get(0)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
430 nd.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
431 }
432 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800433}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800434
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800435void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800436AnnotatedTopologyReader::SaveTopology(const std::string& file)
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800437{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800438 ofstream os(file.c_str(), ios::trunc);
Alexander Afanasyev71029732012-11-19 23:50:52 -0800439 os << "# any empty lines and lines starting with '#' symbol is ignored\n"
440 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800441 << "# The file should contain exactly two sections: router and link, each starting with the "
442 "corresponding keyword\n"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700443 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800444 << "# router section defines topology nodes and their relative positions (e.g., to use in "
445 "visualizer)\n"
Alexander Afanasyev71029732012-11-19 23:50:52 -0800446 << "router\n"
447 << "\n"
448 << "# each line in this section represents one router and should have the following data\n"
449 << "# node comment yPos xPos\n";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700450
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800451 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
452 std::string name = Names::FindName(*node);
453 Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel>();
454 Vector position = mobility->GetPosition();
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800455
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800456 os << name << "\t"
457 << "NA"
458 << "\t" << -position.y << "\t" << position.x << "\n";
459 }
Alexander Afanasyev71029732012-11-19 23:50:52 -0800460
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800461 os
462 << "# link section defines point-to-point links between nodes and characteristics of these "
463 "links\n"
464 << "\n"
465 << "link\n"
466 << "\n"
467 << "# Each line should be in the following format (only first two are required, the rest can "
468 "be omitted)\n"
469 << "# srcNode dstNode bandwidth metric delay queue\n"
470 << "# bandwidth: link bandwidth\n"
471 << "# metric: routing metric\n"
472 << "# delay: link delay\n"
473 << "# queue: MaxPackets for transmission queue on the link (both directions)\n"
474 << "# error: comma-separated list, specifying class for ErrorModel and necessary attributes\n";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800475
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800476 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
477 link++) {
478 os << Names::FindName(link->GetFromNode()) << "\t";
479 os << Names::FindName(link->GetToNode()) << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800480
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800481 string tmp;
482 if (link->GetAttributeFailSafe("DataRate", tmp))
483 os << link->GetAttribute("DataRate") << "\t";
484 else
485 NS_FATAL_ERROR("DataRate must be specified for the link");
Alexander Afanasyev71029732012-11-19 23:50:52 -0800486
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800487 if (link->GetAttributeFailSafe("OSPF", tmp))
488 os << link->GetAttribute("OSPF") << "\t";
489 else
490 os << "1\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800491
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800492 if (link->GetAttributeFailSafe("Delay", tmp)) {
493 os << link->GetAttribute("Delay") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800494
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800495 if (link->GetAttributeFailSafe("MaxPackets", tmp)) {
496 os << link->GetAttribute("MaxPackets") << "\t";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700497
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800498 if (link->GetAttributeFailSafe("LossRate", tmp)) {
499 os << link->GetAttribute("LossRate") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800500 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800501 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700502 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800503 os << "\n";
504 }
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800505}
506
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800507/// @cond include_hidden
508
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800509template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700510class name_writer {
511public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800512 name_writer(Names _names)
513 : names(_names)
514 {
515 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700516
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800517 template<class VertexOrEdge>
518 void
519 operator()(std::ostream& out, const VertexOrEdge& v) const
520 {
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700521 // out << "[label=\"" << names[v] << "\",style=filled,fillcolor=\"" << colors[v] << "\"]";
522 out << "[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
523 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800524
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700525private:
526 Names names;
527};
528
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800529template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700530inline name_writer<Names>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800531make_name_writer(Names n)
532{
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700533 return name_writer<Names>(n);
534}
535
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800536/// @endcond
537
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700538void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800539AnnotatedTopologyReader::SaveGraphviz(const std::string& file)
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700540{
541 typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
542
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800543 typedef boost::property<boost::vertex_name_t, std::string,
544 boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700545
546 typedef boost::no_property edgeProperty;
547
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800548 typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
549 edgeProperty> Graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700550
551 typedef map<string, Traits::vertex_descriptor> node_map_t;
552 node_map_t graphNodes;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800553 Graph graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700554
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800555 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
556 std::pair<node_map_t::iterator, bool> retval = graphNodes.insert(
557 make_pair(Names::FindName(*node), add_vertex(nodeProperty(Names::FindName(*node)), graph)));
558 // NS_ASSERT (ok == true);
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700559
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800560 put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
561 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700562
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800563 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
564 link++) {
565 node_map_t::iterator from = graphNodes.find(Names::FindName(link->GetFromNode()));
566 node_map_t::iterator to = graphNodes.find(Names::FindName(link->GetToNode()));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700567
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800568 // add_edge (node->second, otherNode->second, m_graph);
569 boost::add_edge(from->second, to->second, graph);
570 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700571
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800572 ofstream of(file.c_str());
573 boost::property_map<Graph, boost::vertex_name_t>::type names = get(boost::vertex_name, graph);
574 write_graphviz(of, graph, make_name_writer(names));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700575}
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800576
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800577}