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 <cmath>
22 #include <iostream>
23 #include <sstream>
24
25 // ns3 includes
26 #include "ns3/log.h"
27 #include "ns3/point-to-point-dumbbell.h"
28 #include "ns3/constant-position-mobility-model.h"
29
30 #include "ns3/node-list.h"
31 #include "ns3/point-to-point-net-device.h"
32 #include "ns3/vector.h"
33 #include "ns3/ipv6-address-generator.h"
34
35 namespace ns3 {
36
37 NS_LOG_COMPONENT_DEFINE ("PointToPointDumbbellHelper");
38
PointToPointDumbbellHelper(uint32_t nLeftLeaf,PointToPointHelper leftHelper,uint32_t nRightLeaf,PointToPointHelper rightHelper,PointToPointHelper bottleneckHelper)39 PointToPointDumbbellHelper::PointToPointDumbbellHelper (uint32_t nLeftLeaf,
40 PointToPointHelper leftHelper,
41 uint32_t nRightLeaf,
42 PointToPointHelper rightHelper,
43 PointToPointHelper bottleneckHelper)
44 {
45 // Create the bottleneck routers
46 m_routers.Create (2);
47 // Create the leaf nodes
48 m_leftLeaf.Create (nLeftLeaf);
49 m_rightLeaf.Create (nRightLeaf);
50
51 // Add the link connecting routers
52 m_routerDevices = bottleneckHelper.Install (m_routers);
53 // Add the left side links
54 for (uint32_t i = 0; i < nLeftLeaf; ++i)
55 {
56 NetDeviceContainer c = leftHelper.Install (m_routers.Get (0),
57 m_leftLeaf.Get (i));
58 m_leftRouterDevices.Add (c.Get (0));
59 m_leftLeafDevices.Add (c.Get (1));
60 }
61 // Add the right side links
62 for (uint32_t i = 0; i < nRightLeaf; ++i)
63 {
64 NetDeviceContainer c = rightHelper.Install (m_routers.Get (1),
65 m_rightLeaf.Get (i));
66 m_rightRouterDevices.Add (c.Get (0));
67 m_rightLeafDevices.Add (c.Get (1));
68 }
69 }
70
~PointToPointDumbbellHelper()71 PointToPointDumbbellHelper::~PointToPointDumbbellHelper ()
72 {
73 }
74
GetLeft() const75 Ptr<Node> PointToPointDumbbellHelper::GetLeft () const
76 { // Get the left side bottleneck router
77 return m_routers.Get (0);
78 }
79
GetLeft(uint32_t i) const80 Ptr<Node> PointToPointDumbbellHelper::GetLeft (uint32_t i) const
81 { // Get the i'th left side leaf
82 return m_leftLeaf.Get (i);
83 }
84
GetRight() const85 Ptr<Node> PointToPointDumbbellHelper::GetRight () const
86 { // Get the right side bottleneck router
87 return m_routers.Get (1);
88 }
89
GetRight(uint32_t i) const90 Ptr<Node> PointToPointDumbbellHelper::GetRight (uint32_t i) const
91 { // Get the i'th right side leaf
92 return m_rightLeaf.Get (i);
93 }
94
GetLeftIpv4Address(uint32_t i) const95 Ipv4Address PointToPointDumbbellHelper::GetLeftIpv4Address (uint32_t i) const
96 {
97 return m_leftLeafInterfaces.GetAddress (i);
98 }
99
GetRightIpv4Address(uint32_t i) const100 Ipv4Address PointToPointDumbbellHelper::GetRightIpv4Address (uint32_t i) const
101 {
102 return m_rightLeafInterfaces.GetAddress (i);
103 }
104
GetLeftIpv6Address(uint32_t i) const105 Ipv6Address PointToPointDumbbellHelper::GetLeftIpv6Address (uint32_t i) const
106 {
107 return m_leftLeafInterfaces6.GetAddress (i, 1);
108 }
109
GetRightIpv6Address(uint32_t i) const110 Ipv6Address PointToPointDumbbellHelper::GetRightIpv6Address (uint32_t i) const
111 {
112 return m_rightLeafInterfaces6.GetAddress (i, 1);
113 }
114
LeftCount() const115 uint32_t PointToPointDumbbellHelper::LeftCount () const
116 { // Number of left side nodes
117 return m_leftLeaf.GetN ();
118 }
119
RightCount() const120 uint32_t PointToPointDumbbellHelper::RightCount () const
121 { // Number of right side nodes
122 return m_rightLeaf.GetN ();
123 }
124
InstallStack(InternetStackHelper stack)125 void PointToPointDumbbellHelper::InstallStack (InternetStackHelper stack)
126 {
127 stack.Install (m_routers);
128 stack.Install (m_leftLeaf);
129 stack.Install (m_rightLeaf);
130 }
131
AssignIpv4Addresses(Ipv4AddressHelper leftIp,Ipv4AddressHelper rightIp,Ipv4AddressHelper routerIp)132 void PointToPointDumbbellHelper::AssignIpv4Addresses (Ipv4AddressHelper leftIp,
133 Ipv4AddressHelper rightIp,
134 Ipv4AddressHelper routerIp)
135 {
136 // Assign the router network
137 m_routerInterfaces = routerIp.Assign (m_routerDevices);
138 // Assign to left side
139 for (uint32_t i = 0; i < LeftCount (); ++i)
140 {
141 NetDeviceContainer ndc;
142 ndc.Add (m_leftLeafDevices.Get (i));
143 ndc.Add (m_leftRouterDevices.Get (i));
144 Ipv4InterfaceContainer ifc = leftIp.Assign (ndc);
145 m_leftLeafInterfaces.Add (ifc.Get (0));
146 m_leftRouterInterfaces.Add (ifc.Get (1));
147 leftIp.NewNetwork ();
148 }
149 // Assign to right side
150 for (uint32_t i = 0; i < RightCount (); ++i)
151 {
152 NetDeviceContainer ndc;
153 ndc.Add (m_rightLeafDevices.Get (i));
154 ndc.Add (m_rightRouterDevices.Get (i));
155 Ipv4InterfaceContainer ifc = rightIp.Assign (ndc);
156 m_rightLeafInterfaces.Add (ifc.Get (0));
157 m_rightRouterInterfaces.Add (ifc.Get (1));
158 rightIp.NewNetwork ();
159 }
160 }
161
AssignIpv6Addresses(Ipv6Address addrBase,Ipv6Prefix prefix)162 void PointToPointDumbbellHelper::AssignIpv6Addresses (Ipv6Address addrBase, Ipv6Prefix prefix)
163 {
164 // Assign the router network
165 Ipv6AddressGenerator::Init (addrBase, prefix);
166 Ipv6Address v6network;
167 Ipv6AddressHelper addressHelper;
168
169 v6network = Ipv6AddressGenerator::GetNetwork (prefix);
170 addressHelper.SetBase (v6network, prefix);
171 m_routerInterfaces6 = addressHelper.Assign (m_routerDevices);
172 Ipv6AddressGenerator::NextNetwork (prefix);
173
174 // Assign to left side
175 for (uint32_t i = 0; i < LeftCount (); ++i)
176 {
177 v6network = Ipv6AddressGenerator::GetNetwork (prefix);
178 addressHelper.SetBase (v6network, prefix);
179
180 NetDeviceContainer ndc;
181 ndc.Add (m_leftLeafDevices.Get (i));
182 ndc.Add (m_leftRouterDevices.Get (i));
183 Ipv6InterfaceContainer ifc = addressHelper.Assign (ndc);
184 Ipv6InterfaceContainer::Iterator it = ifc.Begin ();
185 m_leftLeafInterfaces6.Add ((*it).first, (*it).second);
186 it++;
187 m_leftRouterInterfaces6.Add ((*it).first, (*it).second);
188 Ipv6AddressGenerator::NextNetwork (prefix);
189 }
190 // Assign to right side
191 for (uint32_t i = 0; i < RightCount (); ++i)
192 {
193 v6network = Ipv6AddressGenerator::GetNetwork (prefix);
194 addressHelper.SetBase (v6network, prefix);
195
196 NetDeviceContainer ndc;
197 ndc.Add (m_rightLeafDevices.Get (i));
198 ndc.Add (m_rightRouterDevices.Get (i));
199 Ipv6InterfaceContainer ifc = addressHelper.Assign (ndc);
200 Ipv6InterfaceContainer::Iterator it = ifc.Begin ();
201 m_rightLeafInterfaces6.Add ((*it).first, (*it).second);
202 it++;
203 m_rightRouterInterfaces6.Add ((*it).first, (*it).second);
204 Ipv6AddressGenerator::NextNetwork (prefix);
205 }
206 }
207
208
BoundingBox(double ulx,double uly,double lrx,double lry)209 void PointToPointDumbbellHelper::BoundingBox (double ulx, double uly, // Upper left x/y
210 double lrx, double lry) // Lower right x/y
211 {
212 double xDist;
213 double yDist;
214 if (lrx > ulx)
215 {
216 xDist = lrx - ulx;
217 }
218 else
219 {
220 xDist = ulx - lrx;
221 }
222 if (lry > uly)
223 {
224 yDist = lry - uly;
225 }
226 else
227 {
228 yDist = uly - lry;
229 }
230
231 double xAdder = xDist / 3.0;
232 double thetaL = M_PI / (LeftCount () + 1.0);
233 double thetaR = M_PI / (RightCount () + 1.0);
234
235 // Place the left router
236 Ptr<Node> lr = GetLeft ();
237 Ptr<ConstantPositionMobilityModel> loc = lr->GetObject<ConstantPositionMobilityModel> ();
238 if (loc == 0)
239 {
240 loc = CreateObject<ConstantPositionMobilityModel> ();
241 lr->AggregateObject (loc);
242 }
243 Vector lrl (ulx + xAdder, uly + yDist/2.0, 0);
244 loc->SetPosition (lrl);
245
246 // Place the right router
247 Ptr<Node> rr = GetRight ();
248 loc = rr->GetObject<ConstantPositionMobilityModel> ();
249 if (loc == 0)
250 {
251 loc = CreateObject<ConstantPositionMobilityModel> ();
252 rr->AggregateObject (loc);
253 }
254 Vector rrl (ulx + xAdder * 2, uly + yDist/2.0, 0); // Right router location
255 loc->SetPosition (rrl);
256
257 // Place the left leaf nodes
258 double theta = -M_PI_2 + thetaL;
259 for (uint32_t l = 0; l < LeftCount (); ++l)
260 {
261 // Make them in a circular pattern to make all line lengths the same
262 // Special case when theta = 0, to be sure we get a straight line
263 if ((LeftCount () % 2) == 1)
264 { // Count is odd, see if we are in middle
265 if (l == (LeftCount () / 2))
266 {
267 theta = 0.0;
268 }
269 }
270 Ptr<Node> ln = GetLeft (l);
271 loc = ln->GetObject<ConstantPositionMobilityModel> ();
272 if (loc == 0)
273 {
274 loc = CreateObject<ConstantPositionMobilityModel> ();
275 ln->AggregateObject (loc);
276 }
277 Vector lnl (lrl.x - std::cos (theta) * xAdder,
278 lrl.y + std::sin (theta) * xAdder, 0); // Left Node Location
279 // Insure did not exceed bounding box
280 if (lnl.y < uly)
281 {
282 lnl.y = uly; // Set to upper left y
283 }
284 if (lnl.y > lry)
285 {
286 lnl.y = lry; // Set to lower right y
287 }
288 loc->SetPosition (lnl);
289 theta += thetaL;
290 }
291 // Place the right nodes
292 theta = -M_PI_2 + thetaR;
293 for (uint32_t r = 0; r < RightCount (); ++r)
294 {
295 // Special case when theta = 0, to be sure we get a straight line
296 if ((RightCount () % 2) == 1)
297 { // Count is odd, see if we are in middle
298 if (r == (RightCount () / 2))
299 {
300 theta = 0.0;
301 }
302 }
303 Ptr<Node> rn = GetRight (r);
304 loc = rn->GetObject<ConstantPositionMobilityModel> ();
305 if (loc == 0)
306 {
307 loc = CreateObject<ConstantPositionMobilityModel> ();
308 rn->AggregateObject (loc);
309 }
310 Vector rnl (rrl.x + std::cos (theta) * xAdder, // Right node location
311 rrl.y + std::sin (theta) * xAdder, 0);
312 // Insure did not exceed bounding box
313 if (rnl.y < uly)
314 {
315 rnl.y = uly; // Set to upper left y
316 }
317 if (rnl.y > lry)
318 {
319 rnl.y = lry; // Set to lower right y
320 }
321 loc->SetPosition (rnl);
322 theta += thetaR;
323 }
324 }
325
326 } // namespace ns3
327