blob: 4b17ba490523c91e0952a85916925e9ed480be2e [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
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070047using namespace std;
48
49namespace ns3
50{
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070051
52NS_LOG_COMPONENT_DEFINE ("AnnotatedTopologyReader");
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070053
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070054NS_OBJECT_ENSURE_REGISTERED (AnnotatedTopologyReader);
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070055
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070056TypeId AnnotatedTopologyReader::GetTypeId (void)
57{
58 static TypeId tid = TypeId ("ns3::AnnotatedTopologyReader")
59 .SetParent<Object> ()
60 ;
61 return tid;
62}
63
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080064AnnotatedTopologyReader::AnnotatedTopologyReader (const std::string &path)
65 : m_path (path)
66 , m_ulx (0)
67 , m_uly (0)
68 , m_lrx (100.0)
69 , m_lry (100.0)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070070{
71 NS_LOG_FUNCTION (this);
72}
73
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080074void
75AnnotatedTopologyReader::SetBoundingBox (double ulx, double uly, double lrx, double lry)
76{
77 NS_LOG_FUNCTION (this << ulx << uly << lrx << lry);
78
79 m_ulx = ulx;
80 m_uly = uly;
81 m_lrx = lrx;
82 m_lry = lry;
83}
84
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070085AnnotatedTopologyReader::~AnnotatedTopologyReader ()
86{
87 NS_LOG_FUNCTION (this);
88}
89
90NodeContainer
91AnnotatedTopologyReader::Read (void)
92{
93 ifstream topgen;
94 topgen.open (GetFileName ().c_str ());
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -070095 NodeContainer nodes;
96
97 if ( !topgen.is_open () )
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -070098 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -080099 NS_LOG_ERROR ("Cannot open file " << GetFileName () << " for reading");
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700100 return nodes;
101 }
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700102
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700103 int linksNumber = 0;
104 int nodesNumber = 0;
105
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700106 string line;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700107 getline (topgen,line);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800108 istringstream headerLineBuffer (line);
109
110 int totnode;
111 int totlink;
112 headerLineBuffer >> totnode;
113 headerLineBuffer >> totlink;
114
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700115 NS_LOG_INFO ("Annotated topology should have " << totnode << " nodes and " << totlink << " links");
116
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700117 for (int i = 0; i < totlink && !topgen.eof (); i++)
118 {
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700119 getline (topgen,line);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800120 istringstream lineBuffer (line);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700121
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800122 string from;
123 string to;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700124 lineBuffer >> from;
125 lineBuffer >> to;
126
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700127 if ( (!from.empty ()) && (!to.empty ()) )
128 {
129 NS_LOG_INFO ( linksNumber << " From: " << from << " to: " << to );
130
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800131 Ptr<Node> fromNode = Names::Find<Node> (m_path, from);
132 Ptr<Node> toNode = Names::Find<Node> (m_path, to);
133
134 if (fromNode == 0)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700135 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800136 fromNode = CreateObject<Node> ();
137 Names::Add (m_path, from, fromNode);
138 nodes.Add (fromNode);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700139 nodesNumber++;
140 }
141
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800142 if (toNode == 0)
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700143 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800144 toNode = CreateObject<Node> ();
145 Names::Add (m_path, to, toNode);
146 nodes.Add (toNode);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700147 nodesNumber++;
148 }
149
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800150 Link link (fromNode, from, toNode, to);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700151
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800152 string dataRate;
153 lineBuffer >> dataRate;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800154
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800155 string ospf;
156 lineBuffer >> ospf;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700157
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800158 string delay;
159 lineBuffer >> delay;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700160
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800161 string queueSizeNode1;
162 lineBuffer >> queueSizeNode1;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700163
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800164 string queueSizeNode2;
165 lineBuffer >> queueSizeNode2;
166
167 if (dataRate.empty () ||
168 ospf.empty () ||
169 delay.empty () ||
170 queueSizeNode1.empty () ||
171 queueSizeNode2.empty ())
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700172 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800173 NS_LOG_ERROR ("File [" << GetFileName () << ":" << i+2 << " wrong format, skipping");
174 continue;
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700175 }
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800176
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800177 link.SetAttribute ("DataRate", dataRate);
178 link.SetAttribute ("OSPF", ospf);
179 link.SetAttribute ("Delay", delay);
180 link.SetAttribute ("QueueSizeNode1", queueSizeNode1);
181 link.SetAttribute ("QueueSizeNode2", queueSizeNode2);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700182
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700183 AddLink (link);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700184
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700185 linksNumber++;
186 }
187 }
188
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800189 NS_ASSERT (nodesNumber == totnode && linksNumber == totlink);
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700190
191 NS_LOG_INFO ("Annotated topology created with " << nodesNumber << " nodes and " << linksNumber << " links");
192 topgen.close ();
193
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800194 ApplySettings ();
195 AssignCoordinates ();
196
Ilya Moiseenko7dd43be2011-08-18 18:57:12 -0700197 return nodes;
198}
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700199
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800200void
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800201AnnotatedTopologyReader::AssignIpv4Addresses (Ipv4Address base)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800202{
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800203 Ipv4AddressHelper address (base, Ipv4Mask ("/24"));
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700204
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800205 BOOST_FOREACH (const Link &link, m_linksList)
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800206 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800207 address.Assign (NetDeviceContainer (link.GetFromNetDevice (),
208 link.GetToNetDevice ()));
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700209
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800210 base = Ipv4Address (base.Get () + 256);
211 address.SetBase (base, Ipv4Mask ("/24"));
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700212 }
213
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800214 ApplyOspfMetric ();
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700215 }
216
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800217void
218AnnotatedTopologyReader::ApplyOspfMetric ()
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800219 {
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800220 BOOST_FOREACH (const Link &link, m_linksList)
221 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800222 uint16_t metric = boost::lexical_cast<uint16_t> (link.GetAttribute ("OSPF"));
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700223
224 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800225 Ptr<Ipv4> ipv4 = link.GetFromNode ()->GetObject<Ipv4> ();
226 NS_ASSERT (ipv4 != 0);
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800227
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800228 int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetFromNetDevice ());
229 NS_ASSERT (interfaceId >= 0);
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800230
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800231 ipv4->SetMetric (interfaceId,metric);
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700232 }
233
Ilya Moiseenko1eff17d2011-08-17 10:55:53 -0700234 {
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800235 Ptr<Ipv4> ipv4 = link.GetToNode ()->GetObject<Ipv4> ();
236 NS_ASSERT (ipv4 != 0);
237
238 int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetToNetDevice ());
239 NS_ASSERT (interfaceId >= 0);
240
241 ipv4->SetMetric (interfaceId,metric);
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800242 }
243}
Alexander Afanasyev0777f1c2011-12-12 20:22:45 -0800244}
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800245
246void
247AnnotatedTopologyReader::ApplySettings ()
248{
249 PointToPointHelper p2p;
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800250
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800251 // temporary queue, will be changed later
252 p2p.SetQueue ("ns3::DropTailQueue",
253 "MaxPackets", StringValue("100"));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800254
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800255 BOOST_FOREACH (Link &link, m_linksList)
256 {
257 NS_LOG_INFO ("DataRate = " + link.GetAttribute("DataRate")+"Kbps");
258 p2p.SetDeviceAttribute ("DataRate", StringValue(link.GetAttribute("DataRate")+"Kbps"));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800259
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800260 NS_LOG_INFO ("Delay = " + link.GetAttribute("Delay")+"ms");
261 p2p.SetChannelAttribute ("Delay", StringValue(link.GetAttribute("Delay")+"ms"));
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
266 NS_LOG_INFO ("Queue: " << link.GetAttribute("QueueSizeNode1") << " <==> " << link.GetAttribute("QueueSizeNode2"));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800267
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800268 PointerValue txQueueFrom;
269 link.GetFromNetDevice ()->GetAttribute ("TxQueue", txQueueFrom);
270 NS_ASSERT (txQueueFrom.Get<DropTailQueue> () != 0);
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800271
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800272 PointerValue txQueueTo;
273 link.GetToNetDevice ()->GetAttribute ("TxQueue", txQueueTo);
274 NS_ASSERT (txQueueTo.Get<DropTailQueue> () != 0);
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800275
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800276 txQueueFrom.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode1")));
277 txQueueTo. Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode2")));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800278 }
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800279 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800280
281void
282AnnotatedTopologyReader::AssignCoordinates ()
283{
284 UniformVariable randX (m_ulx, m_lrx);
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800285 double x = 0.0;
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800286 UniformVariable randY (m_uly, m_lry);
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800287 double y = 0.0;
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800288
289 BOOST_FOREACH (Link &link, m_linksList)
290 {
291 Ptr<ConstantPositionMobilityModel> loc = link.GetFromNode ()->GetObject<ConstantPositionMobilityModel> ();
292 if (loc != 0)
293 continue; // no need to assign twice
Ilya Moiseenko7e14efa2011-12-12 17:56:22 -0800294
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800295 loc = CreateObject<ConstantPositionMobilityModel> ();
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800296 link.GetFromNode ()->AggregateObject (loc);
297
298 x = randX.GetValue();
299 y = randY.GetValue();
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800300 NS_LOG_INFO("X = "<<x <<"Y = "<<y);
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800301
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800302 loc->SetPosition (Vector (x, y, 0));
Ilya Moiseenko58d26672011-12-08 13:48:06 -0800303 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800304 }
Alexander Afanasyev8633d5d2011-12-12 18:02:31 -0800305
306}