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
54try:
55 from ns import ns
56except ModuleNotFoundError:
57 raise SystemExit(
58 "Error: ns3 Python module not found;"
59 " Python bindings may not be enabled"
60 " or your PYTHONPATH might not be properly configured"
61 )
62
63# #
64# # This function will be used below as a trace sink
65# #
66# static void
67# CourseChangeCallback(std.string path, Ptr<const MobilityModel> model)
68# {
69# Vector position = model.GetPosition();
70# std.cout << "CourseChange " << path << " x=" << position.x << ", y=" << position.y << ", z=" << position.z << std.endl;
71# }
72
73
74def main(argv):
75 #
76 # First, we initialize a few local variables that control some
77 # simulation parameters.
78 #
79 from ctypes import c_double, c_int
80
81 backboneNodes = c_int(10)
82 infraNodes = c_int(2)
83 lanNodes = c_int(2)
84 stopTime = c_double(20)
85 cmd = ns.CommandLine(__file__)
86
87 #
88 # Simulation defaults are typically set next, before command line
89 # arguments are parsed.
90 #
91 ns.core.Config.SetDefault("ns3::OnOffApplication::PacketSize", ns.core.StringValue("1472"))
92 ns.core.Config.SetDefault("ns3::OnOffApplication::DataRate", ns.core.StringValue("100kb/s"))
93
94 #
95 # For convenience, we add the local variables to the command line argument
96 # system so that they can be overridden with flags such as
97 # "--backboneNodes=20"
98 #
99
100 cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes)
101 cmd.AddValue("infraNodes", "number of leaf nodes", infraNodes)
102 cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes)
103 cmd.AddValue["double"]("stopTime", "simulation stop time(seconds)", stopTime)
104
105 #
106 # The system global variables and the local values added to the argument
107 # system can be overridden by command line arguments by using this call.
108 #
109 cmd.Parse(argv)
110
111 if stopTime.value < 10:
112 print("Use a simulation stop time >= 10 seconds")
113 exit(1)
114 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
115 # #
116 # Construct the backbone #
117 # #
118 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
119
120 #
121 # Create a container to manage the nodes of the adhoc(backbone) network.
122 # Later we'll create the rest of the nodes we'll need.
123 #
124 backbone = ns.network.NodeContainer()
125 backbone.Create(backboneNodes.value)
126 #
127 # Create the backbone wifi net devices and install them into the nodes in
128 # our container
129 #
130 wifi = ns.wifi.WifiHelper()
131 mac = ns.wifi.WifiMacHelper()
132 mac.SetType("ns3::AdhocWifiMac")
133 wifi.SetRemoteStationManager(
134 "ns3::ConstantRateWifiManager", "DataMode", ns.core.StringValue("OfdmRate54Mbps")
135 )
136 wifiPhy = ns.wifi.YansWifiPhyHelper()
137 wifiPhy.SetPcapDataLinkType(wifiPhy.DLT_IEEE802_11_RADIO)
138 wifiChannel = ns.wifi.YansWifiChannelHelper.Default()
139 wifiPhy.SetChannel(wifiChannel.Create())
140 backboneDevices = wifi.Install(wifiPhy, mac, backbone)
141 #
142 # Add the IPv4 protocol stack to the nodes in our container
143 #
144 print("Enabling OLSR routing on all backbone nodes")
145 internet = ns.internet.InternetStackHelper()
146 olsr = ns.olsr.OlsrHelper()
147 internet.SetRoutingHelper(olsr)
148 # has effect on the next Install ()
149 internet.Install(backbone)
150 # re-initialize for non-olsr routing.
151 # internet.Reset()
152 #
153 # Assign IPv4 addresses to the device drivers(actually to the associated
154 # IPv4 interfaces) we just created.
155 #
156 ipAddrs = ns.internet.Ipv4AddressHelper()
157 ipAddrs.SetBase(ns.network.Ipv4Address("192.168.0.0"), ns.network.Ipv4Mask("255.255.255.0"))
158 ipAddrs.Assign(backboneDevices)
159
160 #
161 # The ad-hoc network nodes need a mobility model so we aggregate one to
162 # each of the nodes we just finished building.
163 #
164 mobility = ns.mobility.MobilityHelper()
165 mobility.SetPositionAllocator(
166 "ns3::GridPositionAllocator",
167 "MinX",
168 ns.core.DoubleValue(20.0),
169 "MinY",
170 ns.core.DoubleValue(20.0),
171 "DeltaX",
172 ns.core.DoubleValue(20.0),
173 "DeltaY",
174 ns.core.DoubleValue(20.0),
175 "GridWidth",
176 ns.core.UintegerValue(5),
177 "LayoutType",
178 ns.core.StringValue("RowFirst"),
179 )
180 mobility.SetMobilityModel(
181 "ns3::RandomDirection2dMobilityModel",
182 "Bounds",
183 ns.mobility.RectangleValue(ns.mobility.Rectangle(-500, 500, -500, 500)),
184 "Speed",
185 ns.core.StringValue("ns3::ConstantRandomVariable[Constant=2]"),
186 "Pause",
187 ns.core.StringValue("ns3::ConstantRandomVariable[Constant=0.2]"),
188 )
189 mobility.Install(backbone)
190
191 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
192 # #
193 # Construct the LANs #
194 # #
195 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
196
197 # Reset the address base-- all of the CSMA networks will be in
198 # the "172.16 address space
199 ipAddrs.SetBase(ns.network.Ipv4Address("172.16.0.0"), ns.network.Ipv4Mask("255.255.255.0"))
200
201 for i in range(backboneNodes.value):
202 print("Configuring local area network for backbone node ", i)
203 #
204 # Create a container to manage the nodes of the LAN. We need
205 # two containers here; one with all of the new nodes, and one
206 # with all of the nodes including new and existing nodes
207 #
208 newLanNodes = ns.network.NodeContainer()
209 newLanNodes.Create(lanNodes.value - 1)
210 # Now, create the container with all nodes on this link
211 lan = ns.network.NodeContainer(ns.network.NodeContainer(backbone.Get(i)), newLanNodes)
212 #
213 # Create the CSMA net devices and install them into the nodes in our
214 # collection.
215 #
216 csma = ns.csma.CsmaHelper()
217 csma.SetChannelAttribute("DataRate", ns.network.DataRateValue(ns.network.DataRate(5000000)))
218 csma.SetChannelAttribute("Delay", ns.core.TimeValue(ns.core.MilliSeconds(2)))
219 lanDevices = csma.Install(lan)
220 #
221 # Add the IPv4 protocol stack to the new LAN nodes
222 #
223 internet.Install(newLanNodes)
224 #
225 # Assign IPv4 addresses to the device drivers(actually to the
226 # associated IPv4 interfaces) we just created.
227 #
228 ipAddrs.Assign(lanDevices)
229 #
230 # Assign a new network prefix for the next LAN, according to the
231 # network mask initialized above
232 #
233 ipAddrs.NewNetwork()
234 #
235 # The new LAN nodes need a mobility model so we aggregate one
236 # to each of the nodes we just finished building.
237 #
238 mobilityLan = ns.mobility.MobilityHelper()
239 positionAlloc = ns.mobility.ListPositionAllocator()
240 for j in range(newLanNodes.GetN()):
241 positionAlloc.Add(ns.core.Vector(0.0, (j * 10 + 10), 0.0))
242
243 mobilityLan.SetPositionAllocator(positionAlloc)
244 mobilityLan.PushReferenceMobilityModel(backbone.Get(i))
245 mobilityLan.SetMobilityModel("ns3::ConstantPositionMobilityModel")
246 mobilityLan.Install(newLanNodes)
247
248 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
249 # #
250 # Construct the mobile networks #
251 # #
252 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
253
254 # Reset the address base-- all of the 802.11 networks will be in
255 # the "10.0" address space
256 ipAddrs.SetBase(ns.network.Ipv4Address("10.0.0.0"), ns.network.Ipv4Mask("255.255.255.0"))
257 tempRef = [] # list of references to be held to prevent garbage collection
258 for i in range(backboneNodes.value):
259 print("Configuring wireless network for backbone node ", i)
260 #
261 # Create a container to manage the nodes of the LAN. We need
262 # two containers here; one with all of the new nodes, and one
263 # with all of the nodes including new and existing nodes
264 #
265 stas = ns.network.NodeContainer()
266 stas.Create(infraNodes.value - 1)
267 # Now, create the container with all nodes on this link
268 infra = ns.network.NodeContainer(ns.network.NodeContainer(backbone.Get(i)), stas)
269 #
270 # Create another ad hoc network and devices
271 #
272 ssid = ns.wifi.Ssid("wifi-infra" + str(i))
273 wifiInfra = ns.wifi.WifiHelper()
274 wifiPhy.SetChannel(wifiChannel.Create())
275 macInfra = ns.wifi.WifiMacHelper()
276 macInfra.SetType("ns3::StaWifiMac", "Ssid", ns.wifi.SsidValue(ssid))
277
278 # setup stas
279 staDevices = wifiInfra.Install(wifiPhy, macInfra, stas)
280 # setup ap.
281 macInfra.SetType("ns3::ApWifiMac", "Ssid", ns.wifi.SsidValue(ssid))
282 apDevices = wifiInfra.Install(wifiPhy, macInfra, backbone.Get(i))
283 # Collect all of these new devices
284 infraDevices = ns.network.NetDeviceContainer(apDevices, staDevices)
285
286 # Add the IPv4 protocol stack to the nodes in our container
287 #
288 internet.Install(stas)
289 #
290 # Assign IPv4 addresses to the device drivers(actually to the associated
291 # IPv4 interfaces) we just created.
292 #
293 ipAddrs.Assign(infraDevices)
294 #
295 # Assign a new network prefix for each mobile network, according to
296 # the network mask initialized above
297 #
298 ipAddrs.NewNetwork()
299
300 # This call returns an instance that needs to be stored in the outer scope
301 # not to be garbage collected when overwritten in the next iteration
302 subnetAlloc = ns.mobility.ListPositionAllocator()
303
304 # Appending the object to a list is enough to prevent the garbage collection
305 tempRef.append(subnetAlloc)
306
307 #
308 # The new wireless nodes need a mobility model so we aggregate one
309 # to each of the nodes we just finished building.
310 #
311 for j in range(infra.GetN()):
312 subnetAlloc.Add(ns.core.Vector(0.0, j, 0.0))
313
314 mobility.PushReferenceMobilityModel(backbone.Get(i))
315 mobility.SetPositionAllocator(subnetAlloc)
316 mobility.SetMobilityModel(
317 "ns3::RandomDirection2dMobilityModel",
318 "Bounds",
319 ns.mobility.RectangleValue(ns.mobility.Rectangle(-10, 10, -10, 10)),
320 "Speed",
321 ns.core.StringValue("ns3::ConstantRandomVariable[Constant=3]"),
322 "Pause",
323 ns.core.StringValue("ns3::ConstantRandomVariable[Constant=0.4]"),
324 )
325 mobility.Install(stas)
326
327 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
328 # #
329 # Application configuration #
330 # #
331 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
332
333 # Create the OnOff application to send UDP datagrams of size
334 # 210 bytes at a rate of 448 Kb/s, between two nodes
335 print("Create Applications.")
336 port = 9 # Discard port(RFC 863)
337
338 appSource = ns.network.NodeList.GetNode(backboneNodes.value)
339 lastNodeIndex = (
340 backboneNodes.value
341 + backboneNodes.value * (lanNodes.value - 1)
342 + backboneNodes.value * (infraNodes.value - 1)
343 - 1
344 )
345 appSink = ns.network.NodeList.GetNode(lastNodeIndex)
346
347 ns.cppyy.cppdef(
348 """
349 Ipv4Address getIpv4AddressFromNode(Ptr<Node> node){
350 return node->GetObject<Ipv4>()->GetAddress(1,0).GetLocal();
351 }
352 """
353 )
354 # Let's fetch the IP address of the last node, which is on Ipv4Interface 1
355 remoteAddr = ns.cppyy.gbl.getIpv4AddressFromNode(appSink)
356 socketAddr = ns.network.InetSocketAddress(remoteAddr, port)
357 onoff = ns.applications.OnOffHelper("ns3::UdpSocketFactory", socketAddr.ConvertTo())
358 apps = onoff.Install(ns.network.NodeContainer(appSource))
359 apps.Start(ns.core.Seconds(3))
360 apps.Stop(ns.core.Seconds(stopTime.value - 1))
361
362 # Create a packet sink to receive these packets
363 sink = ns.applications.PacketSinkHelper(
364 "ns3::UdpSocketFactory",
365 ns.network.InetSocketAddress(
366 ns.network.InetSocketAddress(ns.network.Ipv4Address.GetAny(), port)
367 ).ConvertTo(),
368 )
369 sinkContainer = ns.network.NodeContainer(appSink)
370 apps = sink.Install(sinkContainer)
371 apps.Start(ns.core.Seconds(3))
372
373 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
374 # #
375 # Tracing configuration #
376 # #
377 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /
378
379 print("Configure Tracing.")
380 csma = ns.csma.CsmaHelper()
381 #
382 # Let's set up some ns-2-like ascii traces, using another helper class
383 #
384 ascii = ns.network.AsciiTraceHelper()
385 stream = ascii.CreateFileStream("mixed-wireless.tr")
386 wifiPhy.EnableAsciiAll(stream)
387 csma.EnableAsciiAll(stream)
388 internet.EnableAsciiIpv4All(stream)
389
390 # Csma captures in non-promiscuous mode
391 csma.EnablePcapAll("mixed-wireless", False)
392 # Let's do a pcap trace on the backbone devices
393 wifiPhy.EnablePcap("mixed-wireless", backboneDevices)
394 wifiPhy.EnablePcap("mixed-wireless", appSink.GetId(), 0)
395
396 # #ifdef ENABLE_FOR_TRACING_EXAMPLE
397 # Config.Connect("/NodeList/*/$MobilityModel/CourseChange",
398 # MakeCallback(&CourseChangeCallback))
399 # #endif
400
401 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
402 # #
403 # Run simulation #
404 # #
405 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
406
407 print("Run Simulation.")
408 ns.core.Simulator.Stop(ns.core.Seconds(stopTime.value))
409 ns.core.Simulator.Run()
410 ns.core.Simulator.Destroy()
411
412
413if __name__ == "__main__":
414 import sys
415
416 main(sys.argv)