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/random-variable.h" 
   42 #include "ns3/error-model.h" 
   43 #include "ns3/constant-position-mobility-model.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");
 
   72   , m_requiredPartitions(1)
 
   74   NS_LOG_FUNCTION(
this);
 
   82   NS_LOG_FUNCTION(
this << ulx << uly << lrx << lry);
 
   84   m_randX = UniformVariable(ulx, lrx);
 
   85   m_randY = UniformVariable(uly, lry);
 
   91   NS_LOG_FUNCTION(
this << model);
 
   92   m_mobilityFactory.SetTypeId(model);
 
   97   NS_LOG_FUNCTION(
this);
 
  103   NS_LOG_FUNCTION(
this << name);
 
  104   m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
 
  106   Ptr<Node> node = CreateObject<Node>(systemId);
 
  108   Names::Add(
m_path, name, node);
 
  118   NS_LOG_FUNCTION(
this << name << posX << posY);
 
  119   m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);
 
  121   Ptr<Node> node = CreateObject<Node>(systemId);
 
  122   Ptr<MobilityModel> loc = DynamicCast<MobilityModel>(m_mobilityFactory.Create());
 
  123   node->AggregateObject(loc);
 
  125   loc->SetPosition(Vector(posX, posY, 0));
 
  127   Names::Add(
m_path, name, node);
 
  139 const std::list<TopologyReader::Link>&
 
  149   topgen.open(GetFileName().c_str());
 
  151   if (!topgen.is_open() || !topgen.good()) {
 
  152     NS_FATAL_ERROR(
"Cannot open file " << GetFileName() << 
" for reading");
 
  156   while (!topgen.eof()) {
 
  158     getline(topgen, line);
 
  160     if (line == 
"router")
 
  165     NS_FATAL_ERROR(
"Topology file " << GetFileName() << 
" does not have \"router\" section");
 
  169   while (!topgen.eof()) {
 
  171     getline(topgen, line);
 
  177     istringstream lineBuffer(line);
 
  179     double latitude = 0, longitude = 0;
 
  180     uint32_t systemId = 0;
 
  182     lineBuffer >> name >> city >> latitude >> longitude >> systemId;
 
  188     if (abs(latitude) > 0.001 && abs(latitude) > 0.001)
 
  189       node = 
CreateNode(name, m_scale * longitude, -m_scale * latitude, systemId);
 
  191       UniformVariable var(0, 200);
 
  192       node = 
CreateNode(name, var.GetValue(), var.GetValue(), systemId);
 
  197   map<string, set<string>> processedLinks; 
 
  200     NS_LOG_ERROR(
"Topology file " << GetFileName() << 
" does not have \"link\" section");
 
  205   while (!topgen.eof()) {
 
  207     getline(topgen, line);
 
  215     istringstream lineBuffer(line);
 
  216     string from, to, capacity, metric, delay, maxPackets, lossRate;
 
  218     lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;
 
  220     if (processedLinks[to].size() != 0
 
  221         && processedLinks[to].find(from) != processedLinks[to].end()) {
 
  224     processedLinks[from].insert(to);
 
  226     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");
 
  231     Link link(fromNode, from, toNode, to);
 
  233     link.SetAttribute(
"DataRate", capacity);
 
  234     link.SetAttribute(
"OSPF", metric);
 
  237       link.SetAttribute(
"Delay", delay);
 
  238     if (!maxPackets.empty())
 
  239       link.SetAttribute(
"MaxPackets", maxPackets);
 
  242     if (!lossRate.empty())
 
  243       link.SetAttribute(
"LossRate", lossRate);
 
  246     NS_LOG_DEBUG(
"New link " << from << 
" <==> " << to << 
" / " << capacity << 
" with " << metric
 
  247                              << 
" metric (" << delay << 
", " << maxPackets << 
", " << lossRate
 
  251   NS_LOG_INFO(
"Annotated topology created with " << 
m_nodes.GetN() << 
" nodes and " << LinksSize()
 
  263   Ipv4AddressHelper address(base, Ipv4Mask(
"/24"));
 
  265   BOOST_FOREACH (
const Link& link, m_linksList) {
 
  266     address.Assign(NetDeviceContainer(link.GetFromNetDevice(), link.GetToNetDevice()));
 
  268     base = Ipv4Address(base.Get() + 256);
 
  269     address.SetBase(base, Ipv4Mask(
"/24"));
 
  276   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"));
 
  281       Ptr<Ipv4> ipv4 = link.GetFromNode()->GetObject<Ipv4>();
 
  283         int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetFromNetDevice());
 
  284         NS_ASSERT(interfaceId >= 0);
 
  286         ipv4->SetMetric(interfaceId, metric);
 
  289       Ptr<ndn::L3Protocol> ndn = link.GetFromNode()->GetObject<
ndn::L3Protocol>();
 
  292         NS_ASSERT(face != 0);
 
  294         face->setMetric(metric);
 
  299       Ptr<Ipv4> ipv4 = link.GetToNode()->GetObject<Ipv4>();
 
  301         int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetToNetDevice());
 
  302         NS_ASSERT(interfaceId >= 0);
 
  304         ipv4->SetMetric(interfaceId, metric);
 
  307       Ptr<ndn::L3Protocol> ndn = link.GetToNode()->GetObject<
ndn::L3Protocol>();
 
  310         NS_ASSERT(face != 0);
 
  312         face->setMetric(metric);
 
  322   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
 
  330   PointToPointHelper p2p;
 
  332   BOOST_FOREACH (Link& link, m_linksList) {
 
  337     if (link.GetAttributeFailSafe(
"MaxPackets", tmp)) {
 
  338       NS_LOG_INFO(
"MaxPackets = " + link.GetAttribute(
"MaxPackets"));
 
  341         uint32_t maxPackets = boost::lexical_cast<uint32_t>(link.GetAttribute(
"MaxPackets"));
 
  344         p2p.SetQueue(
"ns3::DropTailQueue", 
"MaxPackets", UintegerValue(maxPackets));
 
  347         typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
 
  348         std::string value = link.GetAttribute(
"MaxPackets");
 
  349         tokenizer tok(value);
 
  351         tokenizer::iterator token = tok.begin();
 
  352         p2p.SetQueue(*token);
 
  354         for (token++; token != tok.end(); token++) {
 
  355           boost::escaped_list_separator<char> separator(
'\\', 
'=', 
'\"');
 
  356           tokenizer attributeTok(*token, separator);
 
  358           tokenizer::iterator attributeToken = attributeTok.begin();
 
  360           string attribute = *attributeToken;
 
  363           if (attributeToken == attributeTok.end()) {
 
  364             NS_LOG_ERROR(
"Queue attribute [" << *token
 
  365                                              << 
"] should be in form <Attribute>=<Value>");
 
  369           string value = *attributeToken;
 
  371           p2p.SetQueueAttribute(attribute, StringValue(value));
 
  376     if (link.GetAttributeFailSafe(
"DataRate", tmp)) {
 
  377       NS_LOG_INFO(
"DataRate = " + link.GetAttribute(
"DataRate"));
 
  378       p2p.SetDeviceAttribute(
"DataRate", StringValue(link.GetAttribute(
"DataRate")));
 
  381     if (link.GetAttributeFailSafe(
"Delay", tmp)) {
 
  382       NS_LOG_INFO(
"Delay = " + link.GetAttribute(
"Delay"));
 
  383       p2p.SetChannelAttribute(
"Delay", StringValue(link.GetAttribute(
"Delay")));
 
  386     NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
 
  387     link.SetNetDevices(nd.Get(0), nd.Get(1));
 
  390     if (link.GetAttributeFailSafe(
"LossRate", tmp)) {
 
  391       NS_LOG_INFO(
"LinkError = " + link.GetAttribute(
"LossRate"));
 
  393       typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
 
  394       std::string value = link.GetAttribute(
"LossRate");
 
  395       tokenizer tok(value);
 
  397       tokenizer::iterator token = tok.begin();
 
  398       ObjectFactory factory(*token);
 
  400       for (token++; token != tok.end(); token++) {
 
  401         boost::escaped_list_separator<char> separator(
'\\', 
'=', 
'\"');
 
  402         tokenizer attributeTok(*token, separator);
 
  404         tokenizer::iterator attributeToken = attributeTok.begin();
 
  406         string attribute = *attributeToken;
 
  409         if (attributeToken == attributeTok.end()) {
 
  410           NS_LOG_ERROR(
"ErrorModel attribute [" << *token
 
  411                                                 << 
"] should be in form <Attribute>=<Value>");
 
  415         string value = *attributeToken;
 
  417         factory.Set(attribute, StringValue(value));
 
  420       nd.Get(0)->SetAttribute(
"ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
 
  421       nd.Get(1)->SetAttribute(
"ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
 
  429   ofstream os(file.c_str(), ios::trunc);
 
  430   os << 
"# any empty lines and lines starting with '#' symbol is ignored\n" 
  432      << 
"# The file should contain exactly two sections: router and link, each starting with the " 
  433         "corresponding keyword\n" 
  435      << 
"# router section defines topology nodes and their relative positions (e.g., to use in " 
  439      << 
"# each line in this section represents one router and should have the following data\n" 
  440      << 
"# node  comment     yPos    xPos\n";
 
  442   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();
 
  449        << 
"\t" << -position.y << 
"\t" << position.x << 
"\n";
 
  453     << 
"# link section defines point-to-point links between nodes and characteristics of these " 
  458     << 
"# Each line should be in the following format (only first two are required, the rest can " 
  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";
 
  467   for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
 
  469     os << Names::FindName(link->GetFromNode()) << 
"\t";
 
  470     os << Names::FindName(link->GetToNode()) << 
"\t";
 
  473     if (link->GetAttributeFailSafe(
"DataRate", tmp))
 
  474       os << link->GetAttribute(
"DataRate") << 
"\t";
 
  476       NS_FATAL_ERROR(
"DataRate must be specified for the link");
 
  478     if (link->GetAttributeFailSafe(
"OSPF", tmp))
 
  479       os << link->GetAttribute(
"OSPF") << 
"\t";
 
  483     if (link->GetAttributeFailSafe(
"Delay", tmp)) {
 
  484       os << link->GetAttribute(
"Delay") << 
"\t";
 
  486       if (link->GetAttributeFailSafe(
"MaxPackets", tmp)) {
 
  487         os << link->GetAttribute(
"MaxPackets") << 
"\t";
 
  489         if (link->GetAttributeFailSafe(
"LossRate", tmp)) {
 
  490           os << link->GetAttribute(
"LossRate") << 
"\t";
 
  500 template<
class Names>
 
  503   name_writer(Names _names)
 
  508   template<
class VertexOrEdge>
 
  510   operator()(std::ostream& out, 
const VertexOrEdge& v)
 const 
  513     out << 
"[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
 
  520 template<
class Names>
 
  521 inline name_writer<Names>
 
  522 make_name_writer(Names n)
 
  524   return name_writer<Names>(n);
 
  532   typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
 
  534   typedef boost::property<boost::vertex_name_t, std::string,
 
  535                           boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;
 
  537   typedef boost::no_property edgeProperty;
 
  539   typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
 
  542   typedef map<string, Traits::vertex_descriptor> node_map_t;
 
  543   node_map_t graphNodes;
 
  546   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)));
 
  551     put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
 
  554   for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
 
  556     node_map_t::iterator from = graphNodes.find(Names::FindName(link->GetFromNode()));
 
  557     node_map_t::iterator to = graphNodes.find(Names::FindName(link->GetToNode()));
 
  560     boost::add_edge(from->second, to->second, graph);
 
  563   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));
 
shared_ptr< Face > getFaceByNetDevice(Ptr< NetDevice > netDevice) const 
Remove face from ndn stack (remove callbacks) 
 
virtual void ApplyOspfMetric()
Apply OSPF metric on Ipv4 (if exists) and Ccnx (if exists) stacks. 
 
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...
 
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)