blob: 23abc84033e89128ccf5d42ebb2db8e3789bf4ee [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"
Alexander Afanasyevdca091a2015-01-01 20:51:27 -080046
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080047#include <boost/foreach.hpp>
48#include <boost/lexical_cast.hpp>
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070049#include <boost/tokenizer.hpp>
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080050
Alexander Afanasyev455e4412013-05-11 12:51:11 -070051#include <boost/graph/adjacency_list.hpp>
52#include <boost/graph/graphviz.hpp>
53
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080054#include <set>
55
Alexander Afanasyevff6e3692012-07-30 00:11:02 -070056#ifdef NS3_MPI
57#include <ns3/mpi-interface.h>
58#endif
59
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070060using namespace std;
61
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070062namespace ns3 {
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070063
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080064NS_LOG_COMPONENT_DEFINE("AnnotatedTopologyReader");
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070065
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066AnnotatedTopologyReader::AnnotatedTopologyReader(const std::string& path, double scale /*=1.0*/)
67 : m_path(path)
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070068 , m_randX(CreateObject<UniformRandomVariable>())
69 , m_randY(CreateObject<UniformRandomVariable>())
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080070 , m_scale(scale)
71 , m_requiredPartitions(1)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070072{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080073 NS_LOG_FUNCTION(this);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080074
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070075 m_randX->SetAttribute("Min", DoubleValue(0));
76 m_randX->SetAttribute("Max", DoubleValue(100.0));
77
78 m_randY->SetAttribute("Min", DoubleValue(0));
79 m_randY->SetAttribute("Max", DoubleValue(100.0));
80
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080081 SetMobilityModel("ns3::ConstantPositionMobilityModel");
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070082}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070083
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080084void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080085AnnotatedTopologyReader::SetBoundingBox(double ulx, double uly, double lrx, double lry)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080086{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087 NS_LOG_FUNCTION(this << ulx << uly << lrx << lry);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -070088
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -070089 m_randX->SetAttribute("Min", DoubleValue(ulx));
90 m_randX->SetAttribute("Max", DoubleValue(lrx));
91
92 m_randY->SetAttribute("Min", DoubleValue(uly));
93 m_randY->SetAttribute("Max", DoubleValue(lry));
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -080094}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080095
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080096void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080097AnnotatedTopologyReader::SetMobilityModel(const std::string& model)
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -080098{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080099 NS_LOG_FUNCTION(this << model);
100 m_mobilityFactory.SetTypeId(model);
Alexander Afanasyev7dbdcaf2011-12-13 21:40:37 -0800101}
102
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800103AnnotatedTopologyReader::~AnnotatedTopologyReader()
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700104{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105 NS_LOG_FUNCTION(this);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700106}
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800107
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800108Ptr<Node>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800109AnnotatedTopologyReader::CreateNode(const std::string name, uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800110{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800111 NS_LOG_FUNCTION(this << name);
112 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700113
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800114 Ptr<Node> node = CreateObject<Node>(systemId);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800115
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800116 Names::Add(m_path, name, node);
117 m_nodes.Add(node);
Alexander Afanasyev5bcdc992012-11-19 22:25:55 -0800118
119 return node;
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800120}
121
122Ptr<Node>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800123AnnotatedTopologyReader::CreateNode(const std::string name, double posX, double posY,
124 uint32_t systemId)
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800125{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126 NS_LOG_FUNCTION(this << name << posX << posY);
127 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700128
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800129 Ptr<Node> node = CreateObject<Node>(systemId);
130 Ptr<MobilityModel> loc = DynamicCast<MobilityModel>(m_mobilityFactory.Create());
131 node->AggregateObject(loc);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800132
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133 loc->SetPosition(Vector(posX, posY, 0));
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800134
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800135 Names::Add(m_path, name, node);
136 m_nodes.Add(node);
Alexander Afanasyevae3b7c32011-12-13 13:20:06 -0800137
138 return node;
139}
140
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700141NodeContainer
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142AnnotatedTopologyReader::GetNodes() const
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800143{
144 return m_nodes;
145}
146
Alexander Afanasyeve9c9d722012-01-19 16:59:30 -0800147const std::list<TopologyReader::Link>&
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800148AnnotatedTopologyReader::GetLinks() const
Ilya Moiseenkoad9e8ab2012-01-11 19:58:34 -0800149{
150 return m_linksList;
151}
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800152
153NodeContainer
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800154AnnotatedTopologyReader::Read(void)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700155{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800156 ifstream topgen;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800157 topgen.open(GetFileName().c_str());
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700158
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800159 if (!topgen.is_open() || !topgen.good()) {
160 NS_FATAL_ERROR("Cannot open file " << GetFileName() << " for reading");
161 return m_nodes;
162 }
163
164 while (!topgen.eof()) {
165 string line;
166 getline(topgen, line);
167
168 if (line == "router")
169 break;
170 }
171
172 if (topgen.eof()) {
173 NS_FATAL_ERROR("Topology file " << GetFileName() << " does not have \"router\" section");
174 return m_nodes;
175 }
176
177 while (!topgen.eof()) {
178 string line;
179 getline(topgen, line);
180 if (line[0] == '#')
181 continue; // comments
182 if (line == "link")
183 break; // stop reading nodes
184
185 istringstream lineBuffer(line);
186 string name, city;
187 double latitude = 0, longitude = 0;
188 uint32_t systemId = 0;
189
190 lineBuffer >> name >> city >> latitude >> longitude >> systemId;
191 if (name.empty())
192 continue;
193
194 Ptr<Node> node;
195
196 if (abs(latitude) > 0.001 && abs(latitude) > 0.001)
197 node = CreateNode(name, m_scale * longitude, -m_scale * latitude, systemId);
198 else {
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700199 Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
200 node = CreateNode(name, var->GetValue(0, 200), var->GetValue(0, 200), systemId);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201 // node = CreateNode (name, systemId);
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700202 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800203 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800204
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800205 map<string, set<string>> processedLinks; // to eliminate duplications
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800206
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207 if (topgen.eof()) {
208 NS_LOG_ERROR("Topology file " << GetFileName() << " does not have \"link\" section");
209 return m_nodes;
210 }
Alexander Afanasyevb5e54f92012-10-29 10:15:59 -0700211
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700212 // SeekToSection ("link");
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800213 while (!topgen.eof()) {
214 string line;
215 getline(topgen, line);
216 if (line == "")
217 continue;
218 if (line[0] == '#')
219 continue; // comments
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800220
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800221 // NS_LOG_DEBUG ("Input: [" << line << "]");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800222
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800223 istringstream lineBuffer(line);
224 string from, to, capacity, metric, delay, maxPackets, lossRate;
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700225
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800226 lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800227
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800228 if (processedLinks[to].size() != 0
229 && processedLinks[to].find(from) != processedLinks[to].end()) {
230 continue; // duplicated link
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700231 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800232 processedLinks[from].insert(to);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700233
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800234 Ptr<Node> fromNode = Names::Find<Node>(m_path, from);
235 NS_ASSERT_MSG(fromNode != 0, from << " node not found");
236 Ptr<Node> toNode = Names::Find<Node>(m_path, to);
237 NS_ASSERT_MSG(toNode != 0, to << " node not found");
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700238
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800239 Link link(fromNode, from, toNode, to);
240
241 link.SetAttribute("DataRate", capacity);
242 link.SetAttribute("OSPF", metric);
243
244 if (!delay.empty())
245 link.SetAttribute("Delay", delay);
246 if (!maxPackets.empty())
247 link.SetAttribute("MaxPackets", maxPackets);
248
249 // Saran Added lossRate
250 if (!lossRate.empty())
251 link.SetAttribute("LossRate", lossRate);
252
253 AddLink(link);
254 NS_LOG_DEBUG("New link " << from << " <==> " << to << " / " << capacity << " with " << metric
255 << " metric (" << delay << ", " << maxPackets << ", " << lossRate
256 << ")");
257 }
258
259 NS_LOG_INFO("Annotated topology created with " << m_nodes.GetN() << " nodes and " << LinksSize()
260 << " links");
261 topgen.close();
262
263 ApplySettings();
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700264
Alexander Afanasyev5beb35a2011-12-21 16:45:13 -0800265 return m_nodes;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700266}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700267
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800268void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800269AnnotatedTopologyReader::AssignIpv4Addresses(Ipv4Address base)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800270{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800271 Ipv4AddressHelper address(base, Ipv4Mask("/24"));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700272
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800273 BOOST_FOREACH (const Link& link, m_linksList) {
274 address.Assign(NetDeviceContainer(link.GetFromNetDevice(), link.GetToNetDevice()));
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700275
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800276 base = Ipv4Address(base.Get() + 256);
277 address.SetBase(base, Ipv4Mask("/24"));
278 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800279}
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700280
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800281void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800282AnnotatedTopologyReader::ApplyOspfMetric()
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800283{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800284 BOOST_FOREACH (const Link& link, m_linksList) {
285 NS_LOG_DEBUG("OSPF: " << link.GetAttribute("OSPF"));
286 uint16_t metric = boost::lexical_cast<uint16_t>(link.GetAttribute("OSPF"));
287
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800288 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800289 Ptr<Ipv4> ipv4 = link.GetFromNode()->GetObject<Ipv4>();
290 if (ipv4 != 0) {
291 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetFromNetDevice());
292 NS_ASSERT(interfaceId >= 0);
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700293
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800294 ipv4->SetMetric(interfaceId, metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800295 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700296
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800297 Ptr<ndn::L3Protocol> ndn = link.GetFromNode()->GetObject<ndn::L3Protocol>();
298 if (ndn != 0) {
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800299 shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetFromNetDevice());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800300 NS_ASSERT(face != 0);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800301
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800302 face->setMetric(metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800303 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800304 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800305
306 {
307 Ptr<Ipv4> ipv4 = link.GetToNode()->GetObject<Ipv4>();
308 if (ipv4 != 0) {
309 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetToNetDevice());
310 NS_ASSERT(interfaceId >= 0);
311
312 ipv4->SetMetric(interfaceId, metric);
313 }
314
315 Ptr<ndn::L3Protocol> ndn = link.GetToNode()->GetObject<ndn::L3Protocol>();
316 if (ndn != 0) {
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800317 shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetToNetDevice());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800318 NS_ASSERT(face != 0);
319
Alexander Afanasyevdca091a2015-01-01 20:51:27 -0800320 face->setMetric(metric);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800321 }
322 }
323 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800324}
325
326void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800327AnnotatedTopologyReader::ApplySettings()
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800328{
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700329#ifdef NS3_MPI
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800330 if (MpiInterface::IsEnabled() && MpiInterface::GetSize() != m_requiredPartitions) {
331 std::cerr << "MPI interface is enabled, but number of partitions (" << MpiInterface::GetSize()
332 << ") is not equal to number of partitions in the topology (" << m_requiredPartitions
333 << ")";
334 exit(-1);
335 }
Alexander Afanasyevff6e3692012-07-30 00:11:02 -0700336#endif
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700337
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800338 PointToPointHelper p2p;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800339
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800340 BOOST_FOREACH (Link& link, m_linksList) {
341 // cout << "Link: " << Findlink.GetFromNode () << ", " << link.GetToNode () << endl;
342 string tmp;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800343
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800344 ////////////////////////////////////////////////
345 if (link.GetAttributeFailSafe("MaxPackets", tmp)) {
346 NS_LOG_INFO("MaxPackets = " + link.GetAttribute("MaxPackets"));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700347
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800348 try {
349 uint32_t maxPackets = boost::lexical_cast<uint32_t>(link.GetAttribute("MaxPackets"));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700350
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800351 // compatibility mode. Only DropTailQueue is supported
Spyridon Mastorakisf98a3412017-10-30 11:47:58 -0700352 p2p.SetQueue("ns3::DropTailQueue<Packet>", "MaxPackets", UintegerValue(maxPackets));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800353 }
354 catch (...) {
355 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
Alexander Afanasyev66ae18b2015-01-06 18:30:39 -0800356 std::string value = link.GetAttribute("MaxPackets");
357 tokenizer tok(value);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700358
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800359 tokenizer::iterator token = tok.begin();
360 p2p.SetQueue(*token);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700361
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800362 for (token++; token != tok.end(); token++) {
363 boost::escaped_list_separator<char> separator('\\', '=', '\"');
364 tokenizer attributeTok(*token, separator);
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700365
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800366 tokenizer::iterator attributeToken = attributeTok.begin();
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700367
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800368 string attribute = *attributeToken;
369 attributeToken++;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700370
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800371 if (attributeToken == attributeTok.end()) {
372 NS_LOG_ERROR("Queue attribute [" << *token
373 << "] should be in form <Attribute>=<Value>");
374 continue;
375 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700376
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800377 string value = *attributeToken;
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700378
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800379 p2p.SetQueueAttribute(attribute, StringValue(value));
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700380 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800381 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800382 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800383
384 if (link.GetAttributeFailSafe("DataRate", tmp)) {
385 NS_LOG_INFO("DataRate = " + link.GetAttribute("DataRate"));
386 p2p.SetDeviceAttribute("DataRate", StringValue(link.GetAttribute("DataRate")));
387 }
388
389 if (link.GetAttributeFailSafe("Delay", tmp)) {
390 NS_LOG_INFO("Delay = " + link.GetAttribute("Delay"));
391 p2p.SetChannelAttribute("Delay", StringValue(link.GetAttribute("Delay")));
392 }
393
394 NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
395 link.SetNetDevices(nd.Get(0), nd.Get(1));
396
397 ////////////////////////////////////////////////
398 if (link.GetAttributeFailSafe("LossRate", tmp)) {
399 NS_LOG_INFO("LinkError = " + link.GetAttribute("LossRate"));
400
401 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
Alexander Afanasyev66ae18b2015-01-06 18:30:39 -0800402 std::string value = link.GetAttribute("LossRate");
403 tokenizer tok(value);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800404
405 tokenizer::iterator token = tok.begin();
406 ObjectFactory factory(*token);
407
408 for (token++; token != tok.end(); token++) {
409 boost::escaped_list_separator<char> separator('\\', '=', '\"');
410 tokenizer attributeTok(*token, separator);
411
412 tokenizer::iterator attributeToken = attributeTok.begin();
413
414 string attribute = *attributeToken;
415 attributeToken++;
416
417 if (attributeToken == attributeTok.end()) {
418 NS_LOG_ERROR("ErrorModel attribute [" << *token
419 << "] should be in form <Attribute>=<Value>");
420 continue;
421 }
422
423 string value = *attributeToken;
424
425 factory.Set(attribute, StringValue(value));
426 }
427
428 nd.Get(0)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
429 nd.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
430 }
431 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800432}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800433
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800434void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800435AnnotatedTopologyReader::SaveTopology(const std::string& file)
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800436{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800437 ofstream os(file.c_str(), ios::trunc);
Alexander Afanasyev71029732012-11-19 23:50:52 -0800438 os << "# any empty lines and lines starting with '#' symbol is ignored\n"
439 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800440 << "# The file should contain exactly two sections: router and link, each starting with the "
441 "corresponding keyword\n"
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700442 << "\n"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800443 << "# router section defines topology nodes and their relative positions (e.g., to use in "
444 "visualizer)\n"
Alexander Afanasyev71029732012-11-19 23:50:52 -0800445 << "router\n"
446 << "\n"
447 << "# each line in this section represents one router and should have the following data\n"
448 << "# node comment yPos xPos\n";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700449
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800450 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
451 std::string name = Names::FindName(*node);
452 Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel>();
453 Vector position = mobility->GetPosition();
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800454
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800455 os << name << "\t"
456 << "NA"
457 << "\t" << -position.y << "\t" << position.x << "\n";
458 }
Alexander Afanasyev71029732012-11-19 23:50:52 -0800459
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800460 os
461 << "# link section defines point-to-point links between nodes and characteristics of these "
462 "links\n"
463 << "\n"
464 << "link\n"
465 << "\n"
466 << "# Each line should be in the following format (only first two are required, the rest can "
467 "be omitted)\n"
468 << "# srcNode dstNode bandwidth metric delay queue\n"
469 << "# bandwidth: link bandwidth\n"
470 << "# metric: routing metric\n"
471 << "# delay: link delay\n"
472 << "# queue: MaxPackets for transmission queue on the link (both directions)\n"
473 << "# error: comma-separated list, specifying class for ErrorModel and necessary attributes\n";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800474
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800475 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
476 link++) {
477 os << Names::FindName(link->GetFromNode()) << "\t";
478 os << Names::FindName(link->GetToNode()) << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800479
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800480 string tmp;
481 if (link->GetAttributeFailSafe("DataRate", tmp))
482 os << link->GetAttribute("DataRate") << "\t";
483 else
484 NS_FATAL_ERROR("DataRate must be specified for the link");
Alexander Afanasyev71029732012-11-19 23:50:52 -0800485
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800486 if (link->GetAttributeFailSafe("OSPF", tmp))
487 os << link->GetAttribute("OSPF") << "\t";
488 else
489 os << "1\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800490
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800491 if (link->GetAttributeFailSafe("Delay", tmp)) {
492 os << link->GetAttribute("Delay") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800493
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800494 if (link->GetAttributeFailSafe("MaxPackets", tmp)) {
495 os << link->GetAttribute("MaxPackets") << "\t";
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700496
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800497 if (link->GetAttributeFailSafe("LossRate", tmp)) {
498 os << link->GetAttribute("LossRate") << "\t";
Alexander Afanasyev71029732012-11-19 23:50:52 -0800499 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800500 }
Alexander Afanasyevda2f23a2013-04-14 22:52:50 -0700501 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800502 os << "\n";
503 }
Alexander Afanasyeved78b632012-01-25 19:26:43 -0800504}
505
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800506/// @cond include_hidden
507
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800508template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700509class name_writer {
510public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800511 name_writer(Names _names)
512 : names(_names)
513 {
514 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700515
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800516 template<class VertexOrEdge>
517 void
518 operator()(std::ostream& out, const VertexOrEdge& v) const
519 {
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700520 // out << "[label=\"" << names[v] << "\",style=filled,fillcolor=\"" << colors[v] << "\"]";
521 out << "[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
522 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800523
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700524private:
525 Names names;
526};
527
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800528template<class Names>
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700529inline name_writer<Names>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800530make_name_writer(Names n)
531{
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700532 return name_writer<Names>(n);
533}
534
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800535/// @endcond
536
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700537void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800538AnnotatedTopologyReader::SaveGraphviz(const std::string& file)
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700539{
540 typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
541
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800542 typedef boost::property<boost::vertex_name_t, std::string,
543 boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700544
545 typedef boost::no_property edgeProperty;
546
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800547 typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
548 edgeProperty> Graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700549
550 typedef map<string, Traits::vertex_descriptor> node_map_t;
551 node_map_t graphNodes;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800552 Graph graph;
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700553
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800554 for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
555 std::pair<node_map_t::iterator, bool> retval = graphNodes.insert(
556 make_pair(Names::FindName(*node), add_vertex(nodeProperty(Names::FindName(*node)), graph)));
557 // NS_ASSERT (ok == true);
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700558
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800559 put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
560 }
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700561
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800562 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
563 link++) {
564 node_map_t::iterator from = graphNodes.find(Names::FindName(link->GetFromNode()));
565 node_map_t::iterator to = graphNodes.find(Names::FindName(link->GetToNode()));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700566
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800567 // add_edge (node->second, otherNode->second, m_graph);
568 boost::add_edge(from->second, to->second, graph);
569 }
Alexander Afanasyev0aa11362013-07-14 15:35:00 -0700570
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800571 ofstream of(file.c_str());
572 boost::property_map<Graph, boost::vertex_name_t>::type names = get(boost::vertex_name, graph);
573 write_graphviz(of, graph, make_name_writer(names));
Alexander Afanasyev455e4412013-05-11 12:51:11 -0700574}
Spyridon Mastorakis460f57c2014-12-17 00:44:14 -0800575
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800576}