A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
mixed-wired-wireless.py
Go to the documentation of this file.
1# /*
2# * This program is free software; you can redistribute it and/or modify
3# * it under the terms of the GNU General Public License version 2 as
4# * published by the Free Software Foundation;
5# *
6# * This program is distributed in the hope that it will be useful,
7# * but WITHOUT ANY WARRANTY; without even the implied warranty of
8# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9# * GNU General Public License for more details.
10# *
11# * You should have received a copy of the GNU General Public License
12# * along with this program; if not, write to the Free Software
13# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14# *
15# */
16
17#
18# This ns-3 example demonstrates the use of helper functions to ease
19# the construction of simulation scenarios.
20#
21# The simulation topology consists of a mixed wired and wireless
22# scenario in which a hierarchical mobility model is used.
23#
24# The simulation layout consists of N backbone routers interconnected
25# by an ad hoc wifi network.
26# Each backbone router also has a local 802.11 network and is connected
27# to a local LAN. An additional set of(K-1) nodes are connected to
28# this backbone. Finally, a local LAN is connected to each router
29# on the backbone, with L-1 additional hosts.
30#
31# The nodes are populated with TCP/IP stacks, and OLSR unicast routing
32# on the backbone. An example UDP transfer is shown. The simulator
33# be configured to output tcpdumps or traces from different nodes.
34#
35#
36# +--------------------------------------------------------+
37# | |
38# | 802.11 ad hoc, ns-2 mobility |
39# | |
40# +--------------------------------------------------------+
41# | o o o(N backbone routers) |
42# +--------+ +--------+
43# wired LAN | mobile | wired LAN | mobile |
44# -----------| router | -----------| router |
45# --------- ---------
46# | |
47# +----------------+ +----------------+
48# | 802.11 | | 802.11 |
49# | net | | net |
50# | K-1 hosts | | K-1 hosts |
51# +----------------+ +----------------+
52#
53
54from ns import ns
55
56# #
57# # This function will be used below as a trace sink
58# #
59# static void
60# CourseChangeCallback(std.string path, Ptr<const MobilityModel> model)
61# {
62# Vector position = model.GetPosition();
63# std.cout << "CourseChange " << path << " x=" << position.x << ", y=" << position.y << ", z=" << position.z << std.endl;
64# }
65
66def main(argv):
67 #
68 # First, we initialize a few local variables that control some
69 # simulation parameters.
70 #
71 from ctypes import c_int, c_double
72 backboneNodes = c_int(10)
73 infraNodes = c_int(2)
74 lanNodes = c_int(2)
75 stopTime = c_double(20)
76 cmd = ns.CommandLine(__file__)
77
78 #
79 # Simulation defaults are typically set next, before command line
80 # arguments are parsed.
81 #
82 ns.core.Config.SetDefault("ns3::OnOffApplication::PacketSize", ns.core.StringValue("1472"))
83 ns.core.Config.SetDefault("ns3::OnOffApplication::DataRate", ns.core.StringValue("100kb/s"))
84
85 #
86 # For convenience, we add the local variables to the command line argument
87 # system so that they can be overridden with flags such as
88 # "--backboneNodes=20"
89 #
90
91 cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes)
92 cmd.AddValue("infraNodes", "number of leaf nodes", infraNodes)
93 cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes)
94 cmd.AddValue["double"]("stopTime", "simulation stop time(seconds)", stopTime)
95
96 #
97 # The system global variables and the local values added to the argument
98 # system can be overridden by command line arguments by using this call.
99 #
100 cmd.Parse(argv)
101
102 if (stopTime.value < 10):
103 print ("Use a simulation stop time >= 10 seconds")
104 exit(1)
105 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
106 # #
107 # Construct the backbone #
108 # #
109 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
110
111 #
112 # Create a container to manage the nodes of the adhoc(backbone) network.
113 # Later we'll create the rest of the nodes we'll need.
114 #
115 backbone = ns.network.NodeContainer()
116 backbone.Create(backboneNodes.value)
117 #
118 # Create the backbone wifi net devices and install them into the nodes in
119 # our container
120 #
121 wifi = ns.wifi.WifiHelper()
122 mac = ns.wifi.WifiMacHelper()
123 mac.SetType("ns3::AdhocWifiMac")
124 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
125 "DataMode", ns.core.StringValue("OfdmRate54Mbps"))
126 wifiPhy = ns.wifi.YansWifiPhyHelper()
127 wifiPhy.SetPcapDataLinkType(wifiPhy.DLT_IEEE802_11_RADIO)
128 wifiChannel = ns.wifi.YansWifiChannelHelper.Default()
129 wifiPhy.SetChannel(wifiChannel.Create())
130 backboneDevices = wifi.Install(wifiPhy, mac, backbone)
131 #
132 # Add the IPv4 protocol stack to the nodes in our container
133 #
134 print ("Enabling OLSR routing on all backbone nodes")
135 internet = ns.internet.InternetStackHelper()
136 olsr = ns.olsr.OlsrHelper()
137 internet.SetRoutingHelper(olsr); # has effect on the next Install ()
138 internet.Install(backbone);
139 # re-initialize for non-olsr routing.
140 # internet.Reset()
141 #
142 # Assign IPv4 addresses to the device drivers(actually to the associated
143 # IPv4 interfaces) we just created.
144 #
145 ipAddrs = ns.internet.Ipv4AddressHelper()
146 ipAddrs.SetBase(ns.network.Ipv4Address("192.168.0.0"), ns.network.Ipv4Mask("255.255.255.0"))
147 ipAddrs.Assign(backboneDevices)
148
149 #
150 # The ad-hoc network nodes need a mobility model so we aggregate one to
151 # each of the nodes we just finished building.
152 #
153 mobility = ns.mobility.MobilityHelper()
154 mobility.SetPositionAllocator("ns3::GridPositionAllocator",
155 "MinX", ns.core.DoubleValue(20.0),
156 "MinY", ns.core.DoubleValue(20.0),
157 "DeltaX", ns.core.DoubleValue(20.0),
158 "DeltaY", ns.core.DoubleValue(20.0),
159 "GridWidth", ns.core.UintegerValue(5),
160 "LayoutType", ns.core.StringValue("RowFirst"))
161 mobility.SetMobilityModel("ns3::RandomDirection2dMobilityModel",
162 "Bounds", ns.mobility.RectangleValue(ns.mobility.Rectangle(-500, 500, -500, 500)),
163 "Speed", ns.core.StringValue ("ns3::ConstantRandomVariable[Constant=2]"),
164 "Pause", ns.core.StringValue ("ns3::ConstantRandomVariable[Constant=0.2]"))
165 mobility.Install(backbone)
166
167 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
168 # #
169 # Construct the LANs #
170 # #
171 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
172
173 # Reset the address base-- all of the CSMA networks will be in
174 # the "172.16 address space
175 ipAddrs.SetBase(ns.network.Ipv4Address("172.16.0.0"), ns.network.Ipv4Mask("255.255.255.0"))
176
177 for i in range(backboneNodes.value):
178 print ("Configuring local area network for backbone node ", i)
179 #
180 # Create a container to manage the nodes of the LAN. We need
181 # two containers here; one with all of the new nodes, and one
182 # with all of the nodes including new and existing nodes
183 #
184 newLanNodes = ns.network.NodeContainer()
185 newLanNodes.Create(lanNodes.value - 1)
186 # Now, create the container with all nodes on this link
187 lan = ns.network.NodeContainer(ns.network.NodeContainer(backbone.Get(i)), newLanNodes)
188 #
189 # Create the CSMA net devices and install them into the nodes in our
190 # collection.
191 #
192 csma = ns.csma.CsmaHelper()
193 csma.SetChannelAttribute("DataRate", ns.network.DataRateValue(ns.network.DataRate(5000000)))
194 csma.SetChannelAttribute("Delay", ns.core.TimeValue(ns.core.MilliSeconds(2)))
195 lanDevices = csma.Install(lan)
196 #
197 # Add the IPv4 protocol stack to the new LAN nodes
198 #
199 internet.Install(newLanNodes)
200 #
201 # Assign IPv4 addresses to the device drivers(actually to the
202 # associated IPv4 interfaces) we just created.
203 #
204 ipAddrs.Assign(lanDevices)
205 #
206 # Assign a new network prefix for the next LAN, according to the
207 # network mask initialized above
208 #
209 ipAddrs.NewNetwork()
210 #
211 # The new LAN nodes need a mobility model so we aggregate one
212 # to each of the nodes we just finished building.
213 #
214 mobilityLan = ns.mobility.MobilityHelper()
215 positionAlloc = ns.mobility.ListPositionAllocator()
216 for j in range(newLanNodes.GetN()):
217 positionAlloc.Add(ns.core.Vector(0.0, (j*10 + 10), 0.0))
218
219 mobilityLan.SetPositionAllocator(positionAlloc)
220 mobilityLan.PushReferenceMobilityModel(backbone.Get(i))
221 mobilityLan.SetMobilityModel("ns3::ConstantPositionMobilityModel")
222 mobilityLan.Install(newLanNodes);
223
224 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
225 # #
226 # Construct the mobile networks #
227 # #
228 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
229
230 # Reset the address base-- all of the 802.11 networks will be in
231 # the "10.0" address space
232 ipAddrs.SetBase(ns.network.Ipv4Address("10.0.0.0"), ns.network.Ipv4Mask("255.255.255.0"))
233 tempRef = [] # list of references to be held to prevent garbage collection
234 for i in range(backboneNodes.value):
235 print ("Configuring wireless network for backbone node ", i)
236 #
237 # Create a container to manage the nodes of the LAN. We need
238 # two containers here; one with all of the new nodes, and one
239 # with all of the nodes including new and existing nodes
240 #
241 stas = ns.network.NodeContainer()
242 stas.Create(infraNodes.value - 1)
243 # Now, create the container with all nodes on this link
244 infra = ns.network.NodeContainer(ns.network.NodeContainer(backbone.Get(i)), stas)
245 #
246 # Create another ad hoc network and devices
247 #
248 ssid = ns.wifi.Ssid('wifi-infra' + str(i))
249 wifiInfra = ns.wifi.WifiHelper()
250 wifiPhy.SetChannel(wifiChannel.Create())
251 macInfra = ns.wifi.WifiMacHelper();
252 macInfra.SetType("ns3::StaWifiMac",
253 "Ssid", ns.wifi.SsidValue(ssid))
254
255 # setup stas
256 staDevices = wifiInfra.Install(wifiPhy, macInfra, stas)
257 # setup ap.
258 macInfra.SetType("ns3::ApWifiMac",
259 "Ssid", ns.wifi.SsidValue(ssid))
260 apDevices = wifiInfra.Install(wifiPhy, macInfra, backbone.Get(i))
261 # Collect all of these new devices
262 infraDevices = ns.network.NetDeviceContainer(apDevices, staDevices)
263
264 # Add the IPv4 protocol stack to the nodes in our container
265 #
266 internet.Install(stas)
267 #
268 # Assign IPv4 addresses to the device drivers(actually to the associated
269 # IPv4 interfaces) we just created.
270 #
271 ipAddrs.Assign(infraDevices)
272 #
273 # Assign a new network prefix for each mobile network, according to
274 # the network mask initialized above
275 #
276 ipAddrs.NewNetwork()
277
278 # This call returns an instance that needs to be stored in the outer scope
279 # not to be garbage collected when overwritten in the next iteration
280 subnetAlloc = ns.mobility.ListPositionAllocator()
281
282 # Appending the object to a list is enough to prevent the garbage collection
283 tempRef.append(subnetAlloc)
284
285 #
286 # The new wireless nodes need a mobility model so we aggregate one
287 # to each of the nodes we just finished building.
288 #
289 for j in range(infra.GetN()):
290 subnetAlloc.Add(ns.core.Vector(0.0, j, 0.0))
291
292 mobility.PushReferenceMobilityModel(backbone.Get(i))
293 mobility.SetPositionAllocator(subnetAlloc)
294 mobility.SetMobilityModel("ns3::RandomDirection2dMobilityModel",
295 "Bounds", ns.mobility.RectangleValue(ns.mobility.Rectangle(-10, 10, -10, 10)),
296 "Speed", ns.core.StringValue ("ns3::ConstantRandomVariable[Constant=3]"),
297 "Pause", ns.core.StringValue ("ns3::ConstantRandomVariable[Constant=0.4]"))
298 mobility.Install(stas)
299
300 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
301 # #
302 # Application configuration #
303 # #
304 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
305
306 # Create the OnOff application to send UDP datagrams of size
307 # 210 bytes at a rate of 448 Kb/s, between two nodes
308 print ("Create Applications.")
309 port = 9 # Discard port(RFC 863)
310
311 appSource = ns.network.NodeList.GetNode(backboneNodes.value)
312 lastNodeIndex = backboneNodes.value + backboneNodes.value*(lanNodes.value - 1) + backboneNodes.value*(infraNodes.value - 1) - 1
313 appSink = ns.network.NodeList.GetNode(lastNodeIndex)
314
315 ns.cppyy.cppdef("""
316 Ipv4Address getIpv4AddressFromNode(Ptr<Node> node){
317 return node->GetObject<Ipv4>()->GetAddress(1,0).GetLocal();
318 }
319 """)
320 # Let's fetch the IP address of the last node, which is on Ipv4Interface 1
321 remoteAddr = ns.cppyy.gbl.getIpv4AddressFromNode(appSink)
322 socketAddr = ns.network.InetSocketAddress(remoteAddr, port)
323 onoff = ns.applications.OnOffHelper("ns3::UdpSocketFactory", socketAddr.ConvertTo())
324 apps = onoff.Install(ns.network.NodeContainer(appSource))
325 apps.Start(ns.core.Seconds(3))
326 apps.Stop(ns.core.Seconds(stopTime.value - 1))
327
328 # Create a packet sink to receive these packets
329 sink = ns.applications.PacketSinkHelper("ns3::UdpSocketFactory",
330 ns.network.InetSocketAddress(ns.network.InetSocketAddress(ns.network.Ipv4Address.GetAny(), port)).ConvertTo())
331 sinkContainer = ns.network.NodeContainer(appSink)
332 apps = sink.Install(sinkContainer)
333 apps.Start(ns.core.Seconds(3))
334
335 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
336 # #
337 # Tracing configuration #
338 # #
339 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
340
341 print ("Configure Tracing.")
342 csma = ns.csma.CsmaHelper()
343 #
344 # Let's set up some ns-2-like ascii traces, using another helper class
345 #
346 ascii = ns.network.AsciiTraceHelper();
347 stream = ascii.CreateFileStream("mixed-wireless.tr");
348 wifiPhy.EnableAsciiAll(stream);
349 csma.EnableAsciiAll(stream);
350 internet.EnableAsciiIpv4All(stream);
351
352 # Csma captures in non-promiscuous mode
353 csma.EnablePcapAll("mixed-wireless", False)
354 # Let's do a pcap trace on the backbone devices
355 wifiPhy.EnablePcap("mixed-wireless", backboneDevices)
356 wifiPhy.EnablePcap("mixed-wireless", appSink.GetId(), 0)
357
358# #ifdef ENABLE_FOR_TRACING_EXAMPLE
359# Config.Connect("/NodeList/*/$MobilityModel/CourseChange",
360# MakeCallback(&CourseChangeCallback))
361# #endif
362
363
364 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
365 # #
366 # Run simulation #
367 # #
368 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
369
370 print ("Run Simulation.")
371 ns.core.Simulator.Stop(ns.core.Seconds(stopTime.value))
372 ns.core.Simulator.Run()
373 ns.core.Simulator.Destroy()
374
375if __name__ == '__main__':
376 import sys
377 main(sys.argv)
378
379