|
1 |
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 |
/* |
3 |
* This program is free software; you can redistribute it and/or modify |
4 |
* it under the terms of the GNU General Public License version 2 as |
5 |
* published by the Free Software Foundation; |
6 |
* |
7 |
* This program is distributed in the hope that it will be useful, |
8 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 |
* GNU General Public License for more details. |
11 |
* |
12 |
* You should have received a copy of the GNU General Public License |
13 |
* along with this program; if not, write to the Free Software |
14 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
15 |
* |
16 |
* Author: George F. Riley<riley@ece.gatech.edu> |
17 |
*/ |
18 |
|
19 |
// Implement an object to create a dumbbell topology. |
20 |
|
21 |
#include <iostream> |
22 |
#include <sstream> |
23 |
|
24 |
// ns3 includes |
25 |
#include "ns3/animation-interface.h" |
26 |
#include "ns3/point-to-point-dumbbell-helper.h" |
27 |
#include "ns3/constant-position-mobility-model.h" |
28 |
|
29 |
#include "ns3/node-list.h" |
30 |
#include "ns3/point-to-point-net-device.h" |
31 |
#include "ns3/vector.h" |
32 |
|
33 |
NS_LOG_COMPONENT_DEFINE("PointToPointDumbbellHelper"); |
34 |
|
35 |
namespace ns3 { |
36 |
|
37 |
PointToPointDumbbellHelper::PointToPointDumbbellHelper (uint32_t nLeftLeaf, |
38 |
PointToPointHelper leftHelper, |
39 |
uint32_t nRightLeaf, |
40 |
PointToPointHelper rightHelper, |
41 |
PointToPointHelper bottleneckHelper) |
42 |
{ |
43 |
// Create the bottleneck routers |
44 |
m_routers.Create (2); |
45 |
// Create the leaf nodes |
46 |
m_leftLeaf.Create (nLeftLeaf); |
47 |
m_rightLeaf.Create (nRightLeaf); |
48 |
|
49 |
// Add the link connecting routers |
50 |
m_routerDevices = bottleneckHelper.Install (m_routers); |
51 |
// Add the left side links |
52 |
for (uint32_t i = 0; i < nLeftLeaf; ++i) |
53 |
{ |
54 |
NetDeviceContainer c = leftHelper.Install (m_routers.Get (0), |
55 |
m_leftLeaf.Get (i)); |
56 |
m_leftRouterDevices.Add (c.Get (0)); |
57 |
m_leftLeafDevices.Add (c.Get(1)); |
58 |
} |
59 |
// Add the right side links |
60 |
for (uint32_t i = 0; i < nRightLeaf; ++i) |
61 |
{ |
62 |
NetDeviceContainer c = rightHelper.Install (m_routers.Get (1), |
63 |
m_rightLeaf.Get (i)); |
64 |
m_rightRouterDevices.Add (c.Get (0)); |
65 |
m_rightLeafDevices.Add (c.Get (1)); |
66 |
} |
67 |
} |
68 |
|
69 |
PointToPointDumbbellHelper::~PointToPointDumbbellHelper () |
70 |
{} |
71 |
|
72 |
Ptr<Node> PointToPointDumbbellHelper::GetLeft () const |
73 |
{ // Get the left side bottleneck router |
74 |
return m_routers.Get (0); |
75 |
} |
76 |
|
77 |
Ptr<Node> PointToPointDumbbellHelper::GetLeft (uint32_t i) const |
78 |
{ // Get the i'th left side leaf |
79 |
return m_leftLeaf.Get (i); |
80 |
} |
81 |
|
82 |
Ptr<Node> PointToPointDumbbellHelper::GetRight () const |
83 |
{ // Get the right side bottleneck router |
84 |
return m_routers.Get (1); |
85 |
} |
86 |
|
87 |
Ptr<Node> PointToPointDumbbellHelper::GetRight (uint32_t i) const |
88 |
{ // Get the i'th right side leaf |
89 |
return m_rightLeaf.Get (i); |
90 |
} |
91 |
|
92 |
Ipv4Address PointToPointDumbbellHelper::GetLeftIpv4Address (uint32_t i) const |
93 |
{ |
94 |
return m_leftLeafInterfaces.GetAddress (i); |
95 |
} |
96 |
|
97 |
Ipv4Address PointToPointDumbbellHelper::GetRightIpv4Address (uint32_t i) const |
98 |
{ |
99 |
return m_rightLeafInterfaces.GetAddress (i); |
100 |
} |
101 |
|
102 |
uint32_t PointToPointDumbbellHelper::LeftCount () const |
103 |
{ // Number of left side nodes |
104 |
return m_leftLeaf.GetN (); |
105 |
} |
106 |
|
107 |
uint32_t PointToPointDumbbellHelper::RightCount () const |
108 |
{ // Number of right side nodes |
109 |
return m_rightLeaf.GetN (); |
110 |
} |
111 |
|
112 |
void PointToPointDumbbellHelper::InstallStack (InternetStackHelper stack) |
113 |
{ |
114 |
stack.Install (m_routers); |
115 |
stack.Install (m_leftLeaf); |
116 |
stack.Install (m_rightLeaf); |
117 |
} |
118 |
|
119 |
void PointToPointDumbbellHelper::AssignIpv4Addresses (Ipv4AddressHelper leftIp, |
120 |
Ipv4AddressHelper rightIp, |
121 |
Ipv4AddressHelper routerIp) |
122 |
{ |
123 |
// Assign the router network |
124 |
m_routerInterfaces = routerIp.Assign (m_routerDevices); |
125 |
// Assign to left side |
126 |
for (uint32_t i = 0; i < LeftCount (); ++i) |
127 |
{ |
128 |
NetDeviceContainer ndc; |
129 |
ndc.Add (m_leftLeafDevices.Get (i)); |
130 |
ndc.Add (m_leftRouterDevices.Get (i)); |
131 |
Ipv4InterfaceContainer ifc = leftIp.Assign(ndc); |
132 |
m_leftLeafInterfaces.Add (ifc.Get (0)); |
133 |
m_leftRouterInterfaces.Add (ifc.Get (1)); |
134 |
leftIp.NewNetwork (); |
135 |
} |
136 |
// Assign to right side |
137 |
for (uint32_t i = 0; i < RightCount (); ++i) |
138 |
{ |
139 |
NetDeviceContainer ndc; |
140 |
ndc.Add (m_rightLeafDevices.Get (i)); |
141 |
ndc.Add (m_rightRouterDevices.Get (i)); |
142 |
Ipv4InterfaceContainer ifc = rightIp.Assign (ndc); |
143 |
m_rightLeafInterfaces.Add (ifc.Get (0)); |
144 |
m_rightRouterInterfaces.Add (ifc.Get (1)); |
145 |
rightIp.NewNetwork (); |
146 |
} |
147 |
} |
148 |
|
149 |
|
150 |
void PointToPointDumbbellHelper::BoundingBox (double ulx, double uly, // Upper left x/y |
151 |
double lrx, double lry) // Lower right y |
152 |
{ |
153 |
double xDist; |
154 |
double yDist; |
155 |
if (lrx > ulx) |
156 |
{ |
157 |
xDist = lrx - ulx; |
158 |
} |
159 |
else |
160 |
{ |
161 |
xDist = ulx - lrx; |
162 |
} |
163 |
if (lry > uly) |
164 |
{ |
165 |
yDist = lry - uly; |
166 |
} |
167 |
else |
168 |
{ |
169 |
yDist = uly - lry; |
170 |
} |
171 |
|
172 |
double xAdder = xDist / 3.0; |
173 |
double thetaL = M_PI / (LeftCount () + 1.0); |
174 |
double thetaR = M_PI / (RightCount () + 1.0); |
175 |
|
176 |
// Place the left router |
177 |
Ptr<Node> lr = GetLeft (); |
178 |
Ptr<ConstantPositionMobilityModel> loc = lr->GetObject<ConstantPositionMobilityModel> (); |
179 |
if (loc == 0) |
180 |
{ |
181 |
loc = CreateObject<ConstantPositionMobilityModel> (); |
182 |
lr->AggregateObject (loc); |
183 |
} |
184 |
Vector lrl (ulx + xAdder, uly + yDist/2.0, 0); |
185 |
loc->SetPosition (lrl); |
186 |
|
187 |
// Place the right router |
188 |
Ptr<Node> rr = GetRight (); |
189 |
loc = rr->GetObject<ConstantPositionMobilityModel> (); |
190 |
if (loc == 0) |
191 |
{ |
192 |
loc = CreateObject<ConstantPositionMobilityModel> (); |
193 |
rr->AggregateObject (loc); |
194 |
} |
195 |
Vector rrl (ulx + xAdder * 2, uly + yDist/2.0, 0); // Right router location |
196 |
loc->SetPosition (rrl); |
197 |
|
198 |
// Place the left leaf nodes |
199 |
double theta = -M_PI_2 + thetaL; |
200 |
for (uint32_t l = 0; l < LeftCount (); ++l) |
201 |
{ |
202 |
// Make them in a circular pattern to make all line lengths the same |
203 |
// Special case when theta = 0, to be sure we get a straight line |
204 |
if ((LeftCount () % 2) == 1) |
205 |
{ // Count is odd, see if we are in middle |
206 |
if (l == (LeftCount () / 2)) |
207 |
{ |
208 |
theta = 0.0; |
209 |
} |
210 |
} |
211 |
Ptr<Node> ln = GetLeft (l); |
212 |
loc = ln->GetObject<ConstantPositionMobilityModel> (); |
213 |
if (loc == 0) |
214 |
{ |
215 |
loc = CreateObject<ConstantPositionMobilityModel> (); |
216 |
ln->AggregateObject (loc); |
217 |
} |
218 |
Vector lnl (lrl.x - cos (theta) * xAdder, |
219 |
lrl.y + sin (theta) * xAdder, 0); // Left Node Location |
220 |
// Insure did not exceed bounding box |
221 |
if (lnl.y < uly) |
222 |
{ |
223 |
lnl.y = uly; // Set to upper right y |
224 |
} |
225 |
if (lnl.y > lry) |
226 |
{ |
227 |
lnl.y = lry; // Set to lower right y |
228 |
} |
229 |
loc->SetPosition (lnl); |
230 |
theta += thetaL; |
231 |
} |
232 |
// Place the right nodes |
233 |
theta = -M_PI_2 + thetaR; |
234 |
for (uint32_t r = 0; r < RightCount (); ++r) |
235 |
{ |
236 |
// Special case when theta = 0, to be sure we get a straight line |
237 |
if ((RightCount () % 2) == 1) |
238 |
{ // Count is odd, see if we are in middle |
239 |
if (r == (RightCount () / 2)) |
240 |
{ |
241 |
theta = 0.0; |
242 |
} |
243 |
} |
244 |
Ptr<Node> rn = GetRight (r); |
245 |
loc = rn->GetObject<ConstantPositionMobilityModel> (); |
246 |
if (loc == 0) |
247 |
{ |
248 |
loc = CreateObject<ConstantPositionMobilityModel> (); |
249 |
rn->AggregateObject (loc); |
250 |
} |
251 |
Vector rnl (rrl.x + cos (theta) * xAdder, // Right node location |
252 |
rrl.y + sin (theta) * xAdder, 0); |
253 |
// Insure did not exceed bounding box |
254 |
if (rnl.y < uly) |
255 |
{ |
256 |
rnl.y = uly; // Set to upper right y |
257 |
} |
258 |
if (rnl.y > lry) |
259 |
{ |
260 |
rnl.y = lry; // Set to lower right y |
261 |
} |
262 |
loc->SetPosition (rnl); |
263 |
theta += thetaR; |
264 |
} |
265 |
} |
266 |
|
267 |
} // namespace ns3 |