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