blob: 86918f7a5e5e8b9fba411711c725c676e39ff09e [file] [log] [blame]
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
19 */
20
21#include "annotated-topology-reader.h"
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070022
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080023#include "ns3/nstime.h"
24#include "ns3/log.h"
25#include "ns3/assert.h"
26#include "ns3/names.h"
27#include "ns3/net-device-container.h"
28#include "ns3/point-to-point-helper.h"
29#include "ns3/point-to-point-net-device.h"
30#include "ns3/internet-stack-helper.h"
31#include "ns3/ipv4-address-helper.h"
32#include "ns3/ipv4-global-routing-helper.h"
33#include "ns3/drop-tail-queue.h"
34#include "ns3/ipv4-interface.h"
35#include "ns3/ipv4.h"
36#include "ns3/string.h"
37#include "ns3/pointer.h"
38#include "ns3/uinteger.h"
39#include "ns3/ipv4-address.h"
40
41#include "ns3/constant-position-mobility-model.h"
42#include "ns3/random-variable.h"
43
44#include <boost/foreach.hpp>
45#include <boost/lexical_cast.hpp>
46
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080047#include <set>
48
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070049using namespace std;
50
51namespace ns3
52{
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070053
54NS_LOG_COMPONENT_DEFINE ("AnnotatedTopologyReader");
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070055
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070056NS_OBJECT_ENSURE_REGISTERED (AnnotatedTopologyReader);
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070057
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070058TypeId AnnotatedTopologyReader::GetTypeId (void)
59{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080060 static TypeId tid = TypeId ("ns3::AnnotatedTopologyReader")
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070061 .SetParent<Object> ()
62 ;
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080063 return tid;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070064}
65
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080066AnnotatedTopologyReader::AnnotatedTopologyReader (const std::string &path)
67 : m_path (path)
68 , m_ulx (0)
69 , m_uly (0)
70 , m_lrx (100.0)
71 , m_lry (100.0)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070072{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080073 NS_LOG_FUNCTION (this);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070074}
75
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080076void
77AnnotatedTopologyReader::SetBoundingBox (double ulx, double uly, double lrx, double lry)
78{
79 NS_LOG_FUNCTION (this << ulx << uly << lrx << lry);
80
81 m_ulx = ulx;
82 m_uly = uly;
83 m_lrx = lrx;
84 m_lry = lry;
85}
86
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070087AnnotatedTopologyReader::~AnnotatedTopologyReader ()
88{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080089 NS_LOG_FUNCTION (this);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070090}
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080091
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070092NodeContainer
93AnnotatedTopologyReader::Read (void)
94{
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080095 ifstream topgen;
96 topgen.open (GetFileName ().c_str ());
97 NodeContainer nodes;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070098
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -080099 if ( !topgen.is_open () )
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700100 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800101 NS_LOG_ERROR ("Cannot open file " << GetFileName () << " for reading");
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800102 return nodes;
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700103 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800104
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800105 uint32_t linksNumber = 0;
106 uint32_t nodesNumber = 0;
107
108 while (!topgen.eof ())
109 {
110 string line;
111 getline (topgen, line);
112
113 if (line == "router") break;
114 }
115
116 while (!topgen.eof ())
117 {
118 string line;
119 getline (topgen,line);
120 if (line[0] == '#') continue; // comments
121 if (line=="link") break; // stop reading nodes
122
123 istringstream lineBuffer (line);
124 string name, city;
125 double latitude, longitude;
126
127 lineBuffer >> name >> city >> latitude >> longitude;
128 Ptr<Node> node = CreateObject<Node> ();
129 Ptr<ConstantPositionMobilityModel> loc = CreateObject<ConstantPositionMobilityModel> ();
130 node->AggregateObject (loc);
131
Alexander Afanasyev07827182011-12-13 01:07:32 -0800132 loc->SetPosition (Vector (2*longitude, -2*latitude, 0));
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800133
134 Names::Add (m_path, name, node);
135 nodes.Add (node);
136 nodesNumber++;
137 }
138
139 map<string, set<string> > processedLinks; // to eliminate duplications
140
141 // SeekToSection ("link");
142 while (!topgen.eof ())
143 {
144 string line;
145 getline (topgen,line);
146 if (line == "") continue;
147 if (line[0] == '#') continue; // comments
148
149 // NS_LOG_DEBUG ("Input: [" << line << "]");
150
151 istringstream lineBuffer (line);
152 string from, to, capacity, metric;
153
154 lineBuffer >> from >> to >> capacity >> metric;
155
156 if (processedLinks[to].size () != 0 &&
157 processedLinks[to].find (from) != processedLinks[to].end ())
158 {
159 continue; // duplicated link
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700160 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800161 processedLinks[from].insert (to);
162
163 Ptr<Node> fromNode = Names::Find<Node> (m_path, from);
164 NS_ASSERT (fromNode != 0);
165 Ptr<Node> toNode = Names::Find<Node> (m_path, to);
166 NS_ASSERT (fromNode != 0);
167
168 Link link (fromNode, from, toNode, to);
169
170 link.SetAttribute ("DataRate", capacity);
171 link.SetAttribute ("OSPF", metric);
172 // link.SetAttribute ("Delay", delay);
173 // link.SetAttribute ("QueueSizeNode1", queueSizeNode1);
174 // link.SetAttribute ("QueueSizeNode2", queueSizeNode2);
175
176 AddLink (link);
177 NS_LOG_DEBUG ("New link " << from << " <==> " << to << " / " << capacity << "Kbps with " << metric << " metric");
178
179 linksNumber++;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700180 }
181
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800182 NS_LOG_INFO ("Annotated topology created with " << nodesNumber << " nodes and " << linksNumber << " links");
183 topgen.close ();
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700184
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800185 ApplySettings ();
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800186
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800187 return nodes;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700188}
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700189
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800190void
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800191AnnotatedTopologyReader::AssignIpv4Addresses (Ipv4Address base)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800192{
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800193 Ipv4AddressHelper address (base, Ipv4Mask ("/24"));
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700194
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800195 BOOST_FOREACH (const Link &link, m_linksList)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800196 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800197 address.Assign (NetDeviceContainer (link.GetFromNetDevice (),
198 link.GetToNetDevice ()));
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700199
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800200 base = Ipv4Address (base.Get () + 256);
201 address.SetBase (base, Ipv4Mask ("/24"));
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800202 }
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700203
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800204 ApplyOspfMetric ();
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800205}
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700206
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800207void
208AnnotatedTopologyReader::ApplyOspfMetric ()
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800209{
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800210 BOOST_FOREACH (const Link &link, m_linksList)
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800211 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800212 uint16_t metric = boost::lexical_cast<uint16_t> (link.GetAttribute ("OSPF"));
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700213
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800214 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800215 Ptr<Ipv4> ipv4 = link.GetFromNode ()->GetObject<Ipv4> ();
216 NS_ASSERT (ipv4 != 0);
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800217
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800218 int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetFromNetDevice ());
219 NS_ASSERT (interfaceId >= 0);
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800220
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800221 ipv4->SetMetric (interfaceId,metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800222 }
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700223
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800224 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800225 Ptr<Ipv4> ipv4 = link.GetToNode ()->GetObject<Ipv4> ();
226 NS_ASSERT (ipv4 != 0);
227
228 int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetToNetDevice ());
229 NS_ASSERT (interfaceId >= 0);
230
231 ipv4->SetMetric (interfaceId,metric);
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800232 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800233 }
234}
235
236void
237AnnotatedTopologyReader::ApplySettings ()
238{
239 PointToPointHelper p2p;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800240
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800241 // temporary queue, will be changed later
242 p2p.SetQueue ("ns3::DropTailQueue",
243 "MaxPackets", StringValue("100"));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800244
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800245 BOOST_FOREACH (Link &link, m_linksList)
246 {
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800247 string tmp;
248
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800249 NS_LOG_INFO ("DataRate = " + link.GetAttribute("DataRate")+"Kbps");
250 p2p.SetDeviceAttribute ("DataRate", StringValue(link.GetAttribute("DataRate")+"Kbps"));
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800251
252 if (link.GetAttributeFailSafe("Delay", tmp))
253 {
254 NS_LOG_INFO ("Delay = " + link.GetAttribute("Delay")+"ms");
255 p2p.SetChannelAttribute ("Delay", StringValue(link.GetAttribute("Delay")+"ms"));
256 }
257 else
258 {
259 NS_LOG_INFO ("Default delay 1ms");
260 p2p.SetChannelAttribute ("Delay", StringValue("1ms"));
261 }
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800262
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800263 NetDeviceContainer nd = p2p.Install(link.GetFromNode (), link.GetToNode ());
264 link.SetNetDevices (nd.Get (0), nd.Get (1));
265
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800266 // NS_LOG_INFO ("Queue: " << link.GetAttribute("QueueSizeNode1") << " <==> " << link.GetAttribute("QueueSizeNode2"));
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800267
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800268 if (link.GetAttributeFailSafe("QueueSizeNode1", tmp))
269 {
270 PointerValue txQueueFrom;
271 link.GetFromNetDevice ()->GetAttribute ("TxQueue", txQueueFrom);
272 NS_ASSERT (txQueueFrom.Get<DropTailQueue> () != 0);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800273
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800274 txQueueFrom.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode1")));
275 }
276
277 if (link.GetAttributeFailSafe("QueueSizeNode2", tmp))
278 {
279 PointerValue txQueueTo;
280 link.GetToNetDevice ()->GetAttribute ("TxQueue", txQueueTo);
281 NS_ASSERT (txQueueTo.Get<DropTailQueue> () != 0);
Ilya Moiseenko7e14efa2011-12-12 17:56:22 -0800282
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800283 txQueueTo. Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode2")));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800284 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800285 }
Alexander Afanasyev66e6fd72011-12-12 21:34:51 -0800286}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800287
288}