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