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" 47 #include <boost/foreach.hpp> 48 #include <boost/lexical_cast.hpp> 49 #include <boost/tokenizer.hpp> 51 #include <boost/graph/adjacency_list.hpp> 52 #include <boost/graph/graphviz.hpp> 57 #include <ns3/mpi-interface.h> 64 NS_LOG_COMPONENT_DEFINE(
"AnnotatedTopologyReader");
71 , m_requiredPartitions(1)
73 NS_LOG_FUNCTION(
this);
75 m_randX->SetAttribute(
"Min", DoubleValue(0));
76 m_randX->SetAttribute(
"Max", DoubleValue(100.0));
78 m_randY->SetAttribute(
"Min", DoubleValue(0));
79 m_randY->SetAttribute(
"Max", DoubleValue(100.0));
87 NS_LOG_FUNCTION(
this << ulx << uly << lrx << lry);
89 m_randX->SetAttribute(
"Min", DoubleValue(ulx));
90 m_randX->SetAttribute(
"Max", DoubleValue(lrx));
92 m_randY->SetAttribute(
"Min", DoubleValue(uly));
93 m_randY->SetAttribute(
"Max", DoubleValue(lry));
99 NS_LOG_FUNCTION(
this << model);
100 m_mobilityFactory.SetTypeId(model);
105 NS_LOG_FUNCTION(
this);
111 NS_LOG_FUNCTION(
this << name);
112 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
114 Ptr<Node> node = CreateObject<Node>(systemId);
116 Names::Add(
m_path, name, node);
126 NS_LOG_FUNCTION(
this << name << posX << posY);
127 m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
129 Ptr<Node> node = CreateObject<Node>(systemId);
130 Ptr<MobilityModel> loc = DynamicCast<MobilityModel>(m_mobilityFactory.Create());
131 node->AggregateObject(loc);
133 loc->SetPosition(Vector(posX, posY, 0));
135 Names::Add(
m_path, name, node);
147 const std::list<TopologyReader::Link>&
157 topgen.open(GetFileName().c_str());
159 if (!topgen.is_open() || !topgen.good()) {
160 NS_FATAL_ERROR(
"Cannot open file " << GetFileName() <<
" for reading");
164 while (!topgen.eof()) {
166 getline(topgen, line);
168 if (line ==
"router")
173 NS_FATAL_ERROR(
"Topology file " << GetFileName() <<
" does not have \"router\" section");
177 while (!topgen.eof()) {
179 getline(topgen, line);
185 istringstream lineBuffer(line);
187 double latitude = 0, longitude = 0;
188 uint32_t systemId = 0;
190 lineBuffer >> name >> city >> latitude >> longitude >> systemId;
196 if (
abs(latitude) > 0.001 &&
abs(latitude) > 0.001)
197 node =
CreateNode(name, m_scale * longitude, -m_scale * latitude, systemId);
199 Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
200 node =
CreateNode(name, var->GetValue(0, 200), var->GetValue(0, 200), systemId);
205 map<string, set<string>> processedLinks;
208 NS_LOG_ERROR(
"Topology file " << GetFileName() <<
" does not have \"link\" section");
213 while (!topgen.eof()) {
215 getline(topgen, line);
223 istringstream lineBuffer(line);
224 string from, to, capacity, metric,
delay, maxPackets, lossRate;
226 lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;
228 if (processedLinks[to].
size() != 0
229 && processedLinks[to].find(from) != processedLinks[to].end()) {
232 processedLinks[from].insert(to);
234 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");
239 Link link(fromNode, from, toNode, to);
241 link.SetAttribute(
"DataRate", capacity);
242 link.SetAttribute(
"OSPF", metric);
245 link.SetAttribute(
"Delay", delay);
246 if (!maxPackets.empty())
247 link.SetAttribute(
"MaxPackets", maxPackets);
250 if (!lossRate.empty())
251 link.SetAttribute(
"LossRate", lossRate);
254 NS_LOG_DEBUG(
"New link " << from <<
" <==> " << to <<
" / " << capacity <<
" with " << metric
255 <<
" metric (" << delay <<
", " << maxPackets <<
", " << lossRate
259 NS_LOG_INFO(
"Annotated topology created with " <<
m_nodes.GetN() <<
" nodes and " << LinksSize()
271 Ipv4AddressHelper address(base, Ipv4Mask(
"/24"));
273 BOOST_FOREACH (
const Link& link, m_linksList) {
274 address.Assign(NetDeviceContainer(link.GetFromNetDevice(), link.GetToNetDevice()));
276 base = Ipv4Address(base.Get() + 256);
277 address.SetBase(base, Ipv4Mask(
"/24"));
284 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"));
289 Ptr<Ipv4> ipv4 = link.GetFromNode()->GetObject<
Ipv4>();
291 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetFromNetDevice());
292 NS_ASSERT(interfaceId >= 0);
294 ipv4->SetMetric(interfaceId, metric);
300 NS_ASSERT(face != 0);
302 face->setMetric(metric);
307 Ptr<Ipv4> ipv4 = link.GetToNode()->GetObject<
Ipv4>();
309 int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetToNetDevice());
310 NS_ASSERT(interfaceId >= 0);
312 ipv4->SetMetric(interfaceId, metric);
318 NS_ASSERT(face != 0);
320 face->setMetric(metric);
330 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
338 PointToPointHelper p2p;
340 BOOST_FOREACH (Link& link, m_linksList) {
345 if (link.GetAttributeFailSafe(
"MaxPackets", tmp)) {
346 NS_LOG_INFO(
"MaxPackets = " + link.GetAttribute(
"MaxPackets"));
349 std::string maxPackets = link.GetAttribute(
"MaxPackets");
352 p2p.SetQueue(
"ns3::DropTailQueue<Packet>",
"MaxSize", StringValue(maxPackets +
"p"));
355 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
356 std::string
value = link.GetAttribute(
"MaxPackets");
357 tokenizer tok(value);
359 tokenizer::iterator token = tok.begin();
360 p2p.SetQueue(*token);
362 for (token++; token != tok.end(); token++) {
363 boost::escaped_list_separator<char> separator(
'\\',
'=',
'\"');
364 tokenizer attributeTok(*token, separator);
366 tokenizer::iterator attributeToken = attributeTok.begin();
368 string attribute = *attributeToken;
371 if (attributeToken == attributeTok.end()) {
372 NS_LOG_ERROR(
"Queue attribute [" << *token
373 <<
"] should be in form <Attribute>=<Value>");
377 string value = *attributeToken;
379 p2p.SetQueueAttribute(attribute, StringValue(value));
384 if (link.GetAttributeFailSafe(
"DataRate", tmp)) {
385 NS_LOG_INFO(
"DataRate = " + link.GetAttribute(
"DataRate"));
386 p2p.SetDeviceAttribute(
"DataRate", StringValue(link.GetAttribute(
"DataRate")));
389 if (link.GetAttributeFailSafe(
"Delay", tmp)) {
390 NS_LOG_INFO(
"Delay = " + link.GetAttribute(
"Delay"));
391 p2p.SetChannelAttribute(
"Delay", StringValue(link.GetAttribute(
"Delay")));
394 NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
395 link.SetNetDevices(nd.Get(0), nd.Get(1));
398 if (link.GetAttributeFailSafe(
"LossRate", tmp)) {
399 NS_LOG_INFO(
"LinkError = " + link.GetAttribute(
"LossRate"));
401 typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
402 std::string
value = link.GetAttribute(
"LossRate");
403 tokenizer tok(value);
405 tokenizer::iterator token = tok.begin();
406 ObjectFactory factory(*token);
408 for (token++; token != tok.end(); token++) {
409 boost::escaped_list_separator<char> separator(
'\\',
'=',
'\"');
410 tokenizer attributeTok(*token, separator);
412 tokenizer::iterator attributeToken = attributeTok.begin();
414 string attribute = *attributeToken;
417 if (attributeToken == attributeTok.end()) {
418 NS_LOG_ERROR(
"ErrorModel attribute [" << *token
419 <<
"] should be in form <Attribute>=<Value>");
423 string value = *attributeToken;
425 factory.Set(attribute, StringValue(value));
428 nd.Get(0)->SetAttribute(
"ReceiveErrorModel", PointerValue(factory.Create<
ErrorModel>()));
429 nd.Get(1)->SetAttribute(
"ReceiveErrorModel", PointerValue(factory.Create<
ErrorModel>()));
437 ofstream os(file.c_str(), ios::trunc);
438 os <<
"# any empty lines and lines starting with '#' symbol is ignored\n" 440 <<
"# The file should contain exactly two sections: router and link, each starting with the " 441 "corresponding keyword\n" 443 <<
"# router section defines topology nodes and their relative positions (e.g., to use in " 447 <<
"# each line in this section represents one router and should have the following data\n" 448 <<
"# node comment yPos xPos\n";
450 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();
457 <<
"\t" << -position.y <<
"\t" << position.x <<
"\n";
461 <<
"# link section defines point-to-point links between nodes and characteristics of these " 466 <<
"# Each line should be in the following format (only first two are required, the rest can " 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";
475 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
477 os << Names::FindName(link->GetFromNode()) <<
"\t";
478 os << Names::FindName(link->GetToNode()) <<
"\t";
481 if (link->GetAttributeFailSafe(
"DataRate", tmp))
482 os << link->GetAttribute(
"DataRate") <<
"\t";
484 NS_FATAL_ERROR(
"DataRate must be specified for the link");
486 if (link->GetAttributeFailSafe(
"OSPF", tmp))
487 os << link->GetAttribute(
"OSPF") <<
"\t";
491 if (link->GetAttributeFailSafe(
"Delay", tmp)) {
492 os << link->GetAttribute(
"Delay") <<
"\t";
494 if (link->GetAttributeFailSafe(
"MaxPackets", tmp)) {
495 os << link->GetAttribute(
"MaxPackets") <<
"\t";
497 if (link->GetAttributeFailSafe(
"LossRate", tmp)) {
498 os << link->GetAttribute(
"LossRate") <<
"\t";
508 template<
class Names>
511 name_writer(Names _names)
516 template<
class VertexOrEdge>
518 operator()(std::ostream& out,
const VertexOrEdge& v)
const 521 out <<
"[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
528 template<
class Names>
529 inline name_writer<Names>
530 make_name_writer(Names n)
532 return name_writer<Names>(n);
540 typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
542 typedef boost::property<boost::vertex_name_t, std::string,
543 boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;
545 typedef boost::no_property edgeProperty;
547 typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
550 typedef map<string, Traits::vertex_descriptor> node_map_t;
551 node_map_t graphNodes;
554 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)));
559 put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
562 for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
564 node_map_t::iterator from = graphNodes.find(Names::FindName(link->GetFromNode()));
565 node_map_t::iterator to = graphNodes.find(Names::FindName(link->GetToNode()));
568 boost::add_edge(from->second, to->second, graph);
571 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));
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.
shared_ptr< Face > getFaceByNetDevice(Ptr< NetDevice > netDevice) const
Remove face from ndn stack (remove callbacks)
constexpr duration< Rep, Period > abs(duration< Rep, Period > d)
virtual void SetMobilityModel(const std::string &model)
Set mobility model to be used on nodes.
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.
void delay(websocketpp::connection_hdl, long duration)
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()
span_constexpr std::size_t size(span< T, Extent > const &spn)
virtual const std::list< Link > & GetLinks() const
Get links 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)
virtual NodeContainer GetNodes() const
Get nodes read by the reader.