24 #include "ns3/nstime.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" 37 #include "ns3/string.h" 38 #include "ns3/pointer.h" 39 #include "ns3/uinteger.h" 40 #include "ns3/ipv4-address.h" 41 #include "ns3/error-model.h" 42 #include "ns3/constant-position-mobility-model.h" 43 #include "ns3/double.h" 48 #include <boost/foreach.hpp> 49 #include <boost/lexical_cast.hpp> 50 #include <boost/tokenizer.hpp> 52 #include <boost/graph/adjacency_list.hpp> 53 #include <boost/graph/graphviz.hpp> 58 #include <ns3/mpi-interface.h> 65 NS_LOG_COMPONENT_DEFINE(
"AnnotatedTopologyReader");
69 , m_randX(CreateObject<UniformRandomVariable>())
70 , m_randY(CreateObject<UniformRandomVariable>())
72 , m_requiredPartitions(1)
74 NS_LOG_FUNCTION(
this);
76 m_randX->SetAttribute(
"Min", DoubleValue(0));
77 m_randX->SetAttribute(
"Max", DoubleValue(100.0));
79 m_randY->SetAttribute(
"Min", DoubleValue(0));
80 m_randY->SetAttribute(
"Max", DoubleValue(100.0));
88 NS_LOG_FUNCTION(
this << ulx << uly << lrx << lry);
90 m_randX->SetAttribute(
"Min", DoubleValue(ulx));
91 m_randX->SetAttribute(
"Max", DoubleValue(lrx));
93 m_randY->SetAttribute(
"Min", DoubleValue(uly));
94 m_randY->SetAttribute(
"Max", DoubleValue(lry));
100 NS_LOG_FUNCTION(
this << model);
101 m_mobilityFactory.SetTypeId(model);
106 NS_LOG_FUNCTION(
this);
112 NS_LOG_FUNCTION(
this << name);
113 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
115 Ptr<Node> node = CreateObject<Node>(systemId);
117 Names::Add(
m_path, name, node);
127 NS_LOG_FUNCTION(
this << name << posX << posY);
128 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
130 Ptr<Node> node = CreateObject<Node>(systemId);
131 Ptr<MobilityModel> loc = DynamicCast<MobilityModel>(m_mobilityFactory.Create());
132 node->AggregateObject(loc);
134 loc->SetPosition(Vector(posX, posY, 0));
136 Names::Add(
m_path, name, node);
148 const std::list<TopologyReader::Link>&
158 topgen.open(GetFileName().c_str());
160 if (!topgen.is_open() || !topgen.good()) {
161 NS_FATAL_ERROR(
"Cannot open file " << GetFileName() <<
" for reading");
165 while (!topgen.eof()) {
167 getline(topgen, line);
169 if (line ==
"router")
174 NS_FATAL_ERROR(
"Topology file " << GetFileName() <<
" does not have \"router\" section");
178 while (!topgen.eof()) {
180 getline(topgen, line);
186 istringstream lineBuffer(line);
188 double latitude = 0, longitude = 0;
189 uint32_t systemId = 0;
191 lineBuffer >> name >> city >> latitude >> longitude >> systemId;
197 if (abs(latitude) > 0.001 && abs(latitude) > 0.001)
198 node =
CreateNode(name, m_scale * longitude, -m_scale * latitude, systemId);
200 Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
201 node =
CreateNode(name, var->GetValue(0, 200), var->GetValue(0, 200), systemId);
206 map<string, set<string>> processedLinks;
209 NS_LOG_ERROR(
"Topology file " << GetFileName() <<
" does not have \"link\" section");
214 while (!topgen.eof()) {
216 getline(topgen, line);
224 istringstream lineBuffer(line);
225 string from, to, capacity, metric, delay, maxPackets, lossRate;
227 lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;
229 if (processedLinks[to].size() != 0
230 && processedLinks[to].find(from) != processedLinks[to].end()) {
233 processedLinks[from].insert(to);
235 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");
240 Link link(fromNode, from, toNode, to);
242 link.SetAttribute(
"DataRate", capacity);
243 link.SetAttribute(
"OSPF", metric);
246 link.SetAttribute(
"Delay", delay);
247 if (!maxPackets.empty())
248 link.SetAttribute(
"MaxPackets", maxPackets);
251 if (!lossRate.empty())
252 link.SetAttribute(
"LossRate", lossRate);
255 NS_LOG_DEBUG(
"New link " << from <<
" <==> " << to <<
" / " << capacity <<
" with " << metric
256 <<
" metric (" << delay <<
", " << maxPackets <<
", " << lossRate
260 NS_LOG_INFO(
"Annotated topology created with " <<
m_nodes.GetN() <<
" nodes and " << LinksSize()
272 Ipv4AddressHelper address(base, Ipv4Mask(
"/24"));
274 BOOST_FOREACH (
const Link& link, m_linksList) {
275 address.Assign(NetDeviceContainer(link.GetFromNetDevice(), link.GetToNetDevice()));
277 base = Ipv4Address(base.Get() + 256);
278 address.SetBase(base, Ipv4Mask(
"/24"));
285 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"));
290 Ptr<Ipv4> ipv4 = link.GetFromNode()->GetObject<Ipv4>();
292 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetFromNetDevice());
293 NS_ASSERT(interfaceId >= 0);
295 ipv4->SetMetric(interfaceId, metric);
301 NS_ASSERT(face != 0);
303 face->setMetric(metric);
308 Ptr<Ipv4> ipv4 = link.GetToNode()->GetObject<Ipv4>();
310 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetToNetDevice());
311 NS_ASSERT(interfaceId >= 0);
313 ipv4->SetMetric(interfaceId, metric);
319 NS_ASSERT(face != 0);
321 face->setMetric(metric);
331 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
339 PointToPointHelper p2p;
341 BOOST_FOREACH (Link& link, m_linksList) {
346 if (link.GetAttributeFailSafe(
"MaxPackets", tmp)) {
347 NS_LOG_INFO(
"MaxPackets = " + link.GetAttribute(
"MaxPackets"));
350 uint32_t maxPackets = boost::lexical_cast<uint32_t>(link.GetAttribute(
"MaxPackets"));
353 p2p.SetQueue(
"ns3::DropTailQueue",
"MaxPackets", UintegerValue(maxPackets));
356 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
357 std::string value = link.GetAttribute(
"MaxPackets");
358 tokenizer tok(value);
361 p2p.SetQueue(*token);
363 for (token++; token != tok.end(); token++) {
364 boost::escaped_list_separator<char> separator(
'\\',
'=',
'\"');
365 tokenizer attributeTok(*token, separator);
369 string attribute = *attributeToken;
372 if (attributeToken == attributeTok.end()) {
373 NS_LOG_ERROR(
"Queue attribute [" << *token
374 <<
"] should be in form <Attribute>=<Value>");
378 string value = *attributeToken;
380 p2p.SetQueueAttribute(attribute, StringValue(value));
385 if (link.GetAttributeFailSafe(
"DataRate", tmp)) {
386 NS_LOG_INFO(
"DataRate = " + link.GetAttribute(
"DataRate"));
387 p2p.SetDeviceAttribute(
"DataRate", StringValue(link.GetAttribute(
"DataRate")));
390 if (link.GetAttributeFailSafe(
"Delay", tmp)) {
391 NS_LOG_INFO(
"Delay = " + link.GetAttribute(
"Delay"));
392 p2p.SetChannelAttribute(
"Delay", StringValue(link.GetAttribute(
"Delay")));
395 NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
396 link.SetNetDevices(nd.Get(0), nd.Get(1));
399 if (link.GetAttributeFailSafe(
"LossRate", tmp)) {
400 NS_LOG_INFO(
"LinkError = " + link.GetAttribute(
"LossRate"));
402 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
403 std::string value = link.GetAttribute(
"LossRate");
404 tokenizer tok(value);
407 ObjectFactory factory(*token);
409 for (token++; token != tok.end(); token++) {
410 boost::escaped_list_separator<char> separator(
'\\',
'=',
'\"');
411 tokenizer attributeTok(*token, separator);
415 string attribute = *attributeToken;
418 if (attributeToken == attributeTok.end()) {
419 NS_LOG_ERROR(
"ErrorModel attribute [" << *token
420 <<
"] should be in form <Attribute>=<Value>");
424 string value = *attributeToken;
426 factory.Set(attribute, StringValue(value));
429 nd.Get(0)->SetAttribute(
"ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
430 nd.Get(1)->SetAttribute(
"ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
438 ofstream os(file.c_str(), ios::trunc);
439 os <<
"# any empty lines and lines starting with '#' symbol is ignored\n" 441 <<
"# The file should contain exactly two sections: router and link, each starting with the " 442 "corresponding keyword\n" 444 <<
"# router section defines topology nodes and their relative positions (e.g., to use in " 448 <<
"# each line in this section represents one router and should have the following data\n" 449 <<
"# node comment yPos xPos\n";
451 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();
458 <<
"\t" << -position.y <<
"\t" << position.x <<
"\n";
462 <<
"# link section defines point-to-point links between nodes and characteristics of these " 467 <<
"# Each line should be in the following format (only first two are required, the rest can " 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";
476 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
478 os << Names::FindName(link->GetFromNode()) <<
"\t";
479 os << Names::FindName(link->GetToNode()) <<
"\t";
482 if (link->GetAttributeFailSafe(
"DataRate", tmp))
483 os << link->GetAttribute(
"DataRate") <<
"\t";
485 NS_FATAL_ERROR(
"DataRate must be specified for the link");
487 if (link->GetAttributeFailSafe(
"OSPF", tmp))
488 os << link->GetAttribute(
"OSPF") <<
"\t";
492 if (link->GetAttributeFailSafe(
"Delay", tmp)) {
493 os << link->GetAttribute(
"Delay") <<
"\t";
495 if (link->GetAttributeFailSafe(
"MaxPackets", tmp)) {
496 os << link->GetAttribute(
"MaxPackets") <<
"\t";
498 if (link->GetAttributeFailSafe(
"LossRate", tmp)) {
499 os << link->GetAttribute(
"LossRate") <<
"\t";
509 template<
class Names>
512 name_writer(Names _names)
517 template<
class VertexOrEdge>
519 operator()(std::ostream& out,
const VertexOrEdge& v)
const 522 out <<
"[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
529 template<
class Names>
530 inline name_writer<Names>
531 make_name_writer(Names n)
533 return name_writer<Names>(n);
541 typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
543 typedef boost::property<boost::vertex_name_t, std::string,
544 boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;
546 typedef boost::no_property edgeProperty;
548 typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
551 typedef map<string, Traits::vertex_descriptor> node_map_t;
552 node_map_t graphNodes;
555 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)));
560 put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
563 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
569 boost::add_edge(from->second, to->second, graph);
572 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));
shared_ptr< Face > getFaceByNetDevice(Ptr< NetDevice > netDevice) const
Remove face from ndn stack (remove callbacks)
Copyright (c) 2011-2015 Regents of the University of California.
virtual void ApplyOspfMetric()
Apply OSPF metric on Ipv4 (if exists) and Ccnx (if exists) stacks.
Table::const_iterator iterator
virtual void SetMobilityModel(const std::string &model)
Set mobility model to be used on nodes.
virtual const std::list< Link > & GetLinks() const
Get links read by the reader.
virtual void AssignIpv4Addresses(Ipv4Address base)
Assign IPv4 addresses to all links.
virtual void SaveTopology(const std::string &file)
Save positions (e.g., after manual modification using visualizer)
void ApplySettings()
This method applies setting to corresponding nodes and links NetDeviceContainer must be allocated Nod...
Copyright (c) 2011-2015 Regents of the University of California.
virtual void SetBoundingBox(double ulx, double uly, double lrx, double lry)
Set bounding box where nodes will be randomly places (if positions are unspecified) ...
virtual NodeContainer Read()
Main annotated topology reading function.
Implementation network-layer of NDN stack.
virtual ~AnnotatedTopologyReader()
virtual NodeContainer GetNodes() const
Get nodes read by the reader.
virtual void SaveGraphviz(const std::string &file)
Save topology in graphviz format (.dot file)
Ptr< Node > CreateNode(const std::string name, uint32_t systemId)