blob: c62b7e5d0a3de384b2223f73a2ffdc7abf04d454 [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 Afanasyev71029732012-11-19 23:50:52 -080041#include "ns3/random-variable.h"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070042#include "ns3/error-model.h"
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080043#include "ns3/constant-position-mobility-model.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)
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) {
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800291 shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetFromNetDevice());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800292 NS_ASSERT(face != 0);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800293
Alexander Afanasyevdca091a2015-01-01 20:51:27 -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) {
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800309 shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetToNetDevice());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800310 NS_ASSERT(face != 0);
311
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800312 face->setMetric(metric);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800313 }
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;
Alexander Afanasyev66ae18b2015-01-06 18:30:39 -0800348 std::string value = link.GetAttribute("MaxPackets");
349 tokenizer tok(value);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700350
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800351 tokenizer::iterator token = tok.begin();
352 p2p.SetQueue(*token);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700353
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800354 for (token++; token != tok.end(); token++) {
355 boost::escaped_list_separator<char> separator('\\', '=', '\"');
356 tokenizer attributeTok(*token, separator);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700357
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800358 tokenizer::iterator attributeToken = attributeTok.begin();
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700359
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800360 string attribute = *attributeToken;
361 attributeToken++;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700362
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800363 if (attributeToken == attributeTok.end()) {
364 NS_LOG_ERROR("Queue attribute [" << *token
365 << "] should be in form <Attribute>=<Value>");
366 continue;
367 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700368
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800369 string value = *attributeToken;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700370
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800371 p2p.SetQueueAttribute(attribute, StringValue(value));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700372 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800373 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800374 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800375
376 if (link.GetAttributeFailSafe("DataRate", tmp)) {
377 NS_LOG_INFO("DataRate = " + link.GetAttribute("DataRate"));
378 p2p.SetDeviceAttribute("DataRate", StringValue(link.GetAttribute("DataRate")));
379 }
380
381 if (link.GetAttributeFailSafe("Delay", tmp)) {
382 NS_LOG_INFO("Delay = " + link.GetAttribute("Delay"));
383 p2p.SetChannelAttribute("Delay", StringValue(link.GetAttribute("Delay")));
384 }
385
386 NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
387 link.SetNetDevices(nd.Get(0), nd.Get(1));
388
389 ////////////////////////////////////////////////
390 if (link.GetAttributeFailSafe("LossRate", tmp)) {
391 NS_LOG_INFO("LinkError = " + link.GetAttribute("LossRate"));
392
393 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
Alexander Afanasyev66ae18b2015-01-06 18:30:39 -0800394 std::string value = link.GetAttribute("LossRate");
395 tokenizer tok(value);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800396
397 tokenizer::iterator token = tok.begin();
398 ObjectFactory factory(*token);
399
400 for (token++; token != tok.end(); token++) {
401 boost::escaped_list_separator<char> separator('\\', '=', '\"');
402 tokenizer attributeTok(*token, separator);
403
404 tokenizer::iterator attributeToken = attributeTok.begin();
405
406 string attribute = *attributeToken;
407 attributeToken++;
408
409 if (attributeToken == attributeTok.end()) {
410 NS_LOG_ERROR("ErrorModel attribute [" << *token
411 << "] should be in form <Attribute>=<Value>");
412 continue;
413 }
414
415 string value = *attributeToken;
416
417 factory.Set(attribute, StringValue(value));
418 }
419
420 nd.Get(0)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
421 nd.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
422 }
423 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800424}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800425
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800426void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800427AnnotatedTopologyReader::SaveTopology(const std::string& file)
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800428{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800429 ofstream os(file.c_str(), ios::trunc);
Alexander Afanasyev71029732012-11-19 23:50:52 -0800430 os << "# any empty lines and lines starting with '#' symbol is ignored\n"
431 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800432 << "# The file should contain exactly two sections: router and link, each starting with the "
433 "corresponding keyword\n"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700434 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800435 << "# router section defines topology nodes and their relative positions (e.g., to use in "
436 "visualizer)\n"
Alexander Afanasyev71029732012-11-19 23:50:52 -0800437 << "router\n"
438 << "\n"
439 << "# each line in this section represents one router and should have the following data\n"
440 << "# node comment yPos xPos\n";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700441
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800442 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
443 std::string name = Names::FindName(*node);
444 Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel>();
445 Vector position = mobility->GetPosition();
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800446
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800447 os << name << "\t"
448 << "NA"
449 << "\t" << -position.y << "\t" << position.x << "\n";
450 }
Alexander Afanasyev71029732012-11-19 23:50:52 -0800451
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800452 os
453 << "# link section defines point-to-point links between nodes and characteristics of these "
454 "links\n"
455 << "\n"
456 << "link\n"
457 << "\n"
458 << "# Each line should be in the following format (only first two are required, the rest can "
459 "be omitted)\n"
460 << "# srcNode dstNode bandwidth metric delay queue\n"
461 << "# bandwidth: link bandwidth\n"
462 << "# metric: routing metric\n"
463 << "# delay: link delay\n"
464 << "# queue: MaxPackets for transmission queue on the link (both directions)\n"
465 << "# error: comma-separated list, specifying class for ErrorModel and necessary attributes\n";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800466
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800467 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
468 link++) {
469 os << Names::FindName(link->GetFromNode()) << "\t";
470 os << Names::FindName(link->GetToNode()) << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800471
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800472 string tmp;
473 if (link->GetAttributeFailSafe("DataRate", tmp))
474 os << link->GetAttribute("DataRate") << "\t";
475 else
476 NS_FATAL_ERROR("DataRate must be specified for the link");
Alexander Afanasyev71029732012-11-19 23:50:52 -0800477
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800478 if (link->GetAttributeFailSafe("OSPF", tmp))
479 os << link->GetAttribute("OSPF") << "\t";
480 else
481 os << "1\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800482
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800483 if (link->GetAttributeFailSafe("Delay", tmp)) {
484 os << link->GetAttribute("Delay") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800485
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800486 if (link->GetAttributeFailSafe("MaxPackets", tmp)) {
487 os << link->GetAttribute("MaxPackets") << "\t";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700488
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800489 if (link->GetAttributeFailSafe("LossRate", tmp)) {
490 os << link->GetAttribute("LossRate") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800491 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800492 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700493 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800494 os << "\n";
495 }
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800496}
497
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800498/// @cond include_hidden
499
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800500template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700501class name_writer {
502public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800503 name_writer(Names _names)
504 : names(_names)
505 {
506 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700507
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800508 template<class VertexOrEdge>
509 void
510 operator()(std::ostream& out, const VertexOrEdge& v) const
511 {
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700512 // out << "[label=\"" << names[v] << "\",style=filled,fillcolor=\"" << colors[v] << "\"]";
513 out << "[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
514 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800515
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700516private:
517 Names names;
518};
519
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800520template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700521inline name_writer<Names>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800522make_name_writer(Names n)
523{
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700524 return name_writer<Names>(n);
525}
526
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800527/// @endcond
528
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700529void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800530AnnotatedTopologyReader::SaveGraphviz(const std::string& file)
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700531{
532 typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
533
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800534 typedef boost::property<boost::vertex_name_t, std::string,
535 boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700536
537 typedef boost::no_property edgeProperty;
538
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800539 typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
540 edgeProperty> Graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700541
542 typedef map<string, Traits::vertex_descriptor> node_map_t;
543 node_map_t graphNodes;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800544 Graph graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700545
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800546 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
547 std::pair<node_map_t::iterator, bool> retval = graphNodes.insert(
548 make_pair(Names::FindName(*node), add_vertex(nodeProperty(Names::FindName(*node)), graph)));
549 // NS_ASSERT (ok == true);
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700550
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800551 put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
552 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700553
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800554 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
555 link++) {
556 node_map_t::iterator from = graphNodes.find(Names::FindName(link->GetFromNode()));
557 node_map_t::iterator to = graphNodes.find(Names::FindName(link->GetToNode()));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700558
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800559 // add_edge (node->second, otherNode->second, m_graph);
560 boost::add_edge(from->second, to->second, graph);
561 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700562
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800563 ofstream of(file.c_str());
564 boost::property_map<Graph, boost::vertex_name_t>::type names = get(boost::vertex_name, graph);
565 write_graphviz(of, graph, make_name_writer(names));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700566}
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800567
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800568}