A Discrete-Event Network Simulator
API
mixed-wired-wireless.cc
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 // | infra net | | infra net |
50 // | K-1 hosts | | K-1 hosts |
51 // +----------------+ +----------------+
52 //
53 // We'll send data from the first wired LAN node on the first wired LAN
54 // to the last wireless STA on the last infrastructure net, thereby
55 // causing packets to traverse CSMA to adhoc to infrastructure links
56 //
57 // Note that certain mobility patterns may cause packet forwarding
58 // to fail (if nodes become disconnected)
59 
60 #include "ns3/animation-interface.h"
61 #include "ns3/command-line.h"
62 #include "ns3/csma-helper.h"
63 #include "ns3/internet-stack-helper.h"
64 #include "ns3/ipv4-address-helper.h"
65 #include "ns3/mobility-helper.h"
66 #include "ns3/olsr-helper.h"
67 #include "ns3/on-off-helper.h"
68 #include "ns3/packet-sink-helper.h"
69 #include "ns3/qos-txop.h"
70 #include "ns3/ssid.h"
71 #include "ns3/string.h"
72 #include "ns3/yans-wifi-channel.h"
73 #include "ns3/yans-wifi-helper.h"
74 
75 using namespace ns3;
76 
77 //
78 // Define logging keyword for this file
79 //
80 NS_LOG_COMPONENT_DEFINE("MixedWireless");
81 
89 static void
91 {
92  Vector position = model->GetPosition();
93  std::cout << "CourseChange " << path << " x=" << position.x << ", y=" << position.y
94  << ", z=" << position.z << std::endl;
95 }
96 
97 int
98 main(int argc, char* argv[])
99 {
100  //
101  // First, we declare and initialize a few local variables that control some
102  // simulation parameters.
103  //
104  uint32_t backboneNodes = 10;
105  uint32_t infraNodes = 2;
106  uint32_t lanNodes = 2;
107  uint32_t stopTime = 20;
108  bool useCourseChangeCallback = false;
109 
110  //
111  // Simulation defaults are typically set next, before command line
112  // arguments are parsed.
113  //
114  Config::SetDefault("ns3::OnOffApplication::PacketSize", StringValue("1472"));
115  Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue("100kb/s"));
116 
117  //
118  // For convenience, we add the local variables to the command line argument
119  // system so that they can be overridden with flags such as
120  // "--backboneNodes=20"
121  //
122  CommandLine cmd(__FILE__);
123  cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes);
124  cmd.AddValue("infraNodes", "number of leaf nodes", infraNodes);
125  cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes);
126  cmd.AddValue("stopTime", "simulation stop time (seconds)", stopTime);
127  cmd.AddValue("useCourseChangeCallback",
128  "whether to enable course change tracing",
129  useCourseChangeCallback);
130 
131  //
132  // The system global variables and the local values added to the argument
133  // system can be overridden by command line arguments by using this call.
134  //
135  cmd.Parse(argc, argv);
136 
137  if (stopTime < 10)
138  {
139  std::cout << "Use a simulation stop time >= 10 seconds" << std::endl;
140  exit(1);
141  }
143  // //
144  // Construct the backbone //
145  // //
147 
148  //
149  // Create a container to manage the nodes of the adhoc (backbone) network.
150  // Later we'll create the rest of the nodes we'll need.
151  //
152  NodeContainer backbone;
153  backbone.Create(backboneNodes);
154  //
155  // Create the backbone wifi net devices and install them into the nodes in
156  // our container
157  //
160  mac.SetType("ns3::AdhocWifiMac");
161  wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
162  "DataMode",
163  StringValue("OfdmRate54Mbps"));
164  YansWifiPhyHelper wifiPhy;
167  wifiPhy.SetChannel(wifiChannel.Create());
168  NetDeviceContainer backboneDevices = wifi.Install(wifiPhy, mac, backbone);
169 
170  // We enable OLSR (which will be consulted at a higher priority than
171  // the global routing) on the backbone ad hoc nodes
172  NS_LOG_INFO("Enabling OLSR routing on all backbone nodes");
174  //
175  // Add the IPv4 protocol stack to the nodes in our container
176  //
178  internet.SetRoutingHelper(olsr); // has effect on the next Install ()
179  internet.Install(backbone);
180 
181  //
182  // Assign IPv4 addresses to the device drivers (actually to the associated
183  // IPv4 interfaces) we just created.
184  //
185  Ipv4AddressHelper ipAddrs;
186  ipAddrs.SetBase("192.168.0.0", "255.255.255.0");
187  ipAddrs.Assign(backboneDevices);
188 
189  //
190  // The ad-hoc network nodes need a mobility model so we aggregate one to
191  // each of the nodes we just finished building.
192  //
194  mobility.SetPositionAllocator("ns3::GridPositionAllocator",
195  "MinX",
196  DoubleValue(20.0),
197  "MinY",
198  DoubleValue(20.0),
199  "DeltaX",
200  DoubleValue(20.0),
201  "DeltaY",
202  DoubleValue(20.0),
203  "GridWidth",
204  UintegerValue(5),
205  "LayoutType",
206  StringValue("RowFirst"));
207  mobility.SetMobilityModel("ns3::RandomDirection2dMobilityModel",
208  "Bounds",
209  RectangleValue(Rectangle(-500, 500, -500, 500)),
210  "Speed",
211  StringValue("ns3::ConstantRandomVariable[Constant=2]"),
212  "Pause",
213  StringValue("ns3::ConstantRandomVariable[Constant=0.2]"));
214  mobility.Install(backbone);
215 
217  // //
218  // Construct the LANs //
219  // //
221 
222  // Reset the address base-- all of the CSMA networks will be in
223  // the "172.16 address space
224  ipAddrs.SetBase("172.16.0.0", "255.255.255.0");
225 
226  for (uint32_t i = 0; i < backboneNodes; ++i)
227  {
228  NS_LOG_INFO("Configuring local area network for backbone node " << i);
229  //
230  // Create a container to manage the nodes of the LAN. We need
231  // two containers here; one with all of the new nodes, and one
232  // with all of the nodes including new and existing nodes
233  //
234  NodeContainer newLanNodes;
235  newLanNodes.Create(lanNodes - 1);
236  // Now, create the container with all nodes on this link
237  NodeContainer lan(backbone.Get(i), newLanNodes);
238  //
239  // Create the CSMA net devices and install them into the nodes in our
240  // collection.
241  //
243  csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
244  csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
245  NetDeviceContainer lanDevices = csma.Install(lan);
246  //
247  // Add the IPv4 protocol stack to the new LAN nodes
248  //
249  internet.Install(newLanNodes);
250  //
251  // Assign IPv4 addresses to the device drivers (actually to the
252  // associated IPv4 interfaces) we just created.
253  //
254  ipAddrs.Assign(lanDevices);
255  //
256  // Assign a new network prefix for the next LAN, according to the
257  // network mask initialized above
258  //
259  ipAddrs.NewNetwork();
260  //
261  // The new LAN nodes need a mobility model so we aggregate one
262  // to each of the nodes we just finished building.
263  //
264  MobilityHelper mobilityLan;
265  Ptr<ListPositionAllocator> subnetAlloc = CreateObject<ListPositionAllocator>();
266  for (uint32_t j = 0; j < newLanNodes.GetN(); ++j)
267  {
268  subnetAlloc->Add(Vector(0.0, j * 10 + 10, 0.0));
269  }
270  mobilityLan.PushReferenceMobilityModel(backbone.Get(i));
271  mobilityLan.SetPositionAllocator(subnetAlloc);
272  mobilityLan.SetMobilityModel("ns3::ConstantPositionMobilityModel");
273  mobilityLan.Install(newLanNodes);
274  }
275 
277  // //
278  // Construct the mobile networks //
279  // //
281 
282  // Reset the address base-- all of the 802.11 networks will be in
283  // the "10.0" address space
284  ipAddrs.SetBase("10.0.0.0", "255.255.255.0");
285 
286  for (uint32_t i = 0; i < backboneNodes; ++i)
287  {
288  NS_LOG_INFO("Configuring wireless network for backbone node " << i);
289  //
290  // Create a container to manage the nodes of the LAN. We need
291  // two containers here; one with all of the new nodes, and one
292  // with all of the nodes including new and existing nodes
293  //
294  NodeContainer stas;
295  stas.Create(infraNodes - 1);
296  // Now, create the container with all nodes on this link
297  NodeContainer infra(backbone.Get(i), stas);
298  //
299  // Create an infrastructure network
300  //
301  WifiHelper wifiInfra;
302  WifiMacHelper macInfra;
303  wifiPhy.SetChannel(wifiChannel.Create());
304  // Create unique ssids for these networks
305  std::string ssidString("wifi-infra");
306  std::stringstream ss;
307  ss << i;
308  ssidString += ss.str();
309  Ssid ssid = Ssid(ssidString);
310  // setup stas
311  macInfra.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
312  NetDeviceContainer staDevices = wifiInfra.Install(wifiPhy, macInfra, stas);
313  // setup ap.
314  macInfra.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
315  NetDeviceContainer apDevices = wifiInfra.Install(wifiPhy, macInfra, backbone.Get(i));
316  // Collect all of these new devices
317  NetDeviceContainer infraDevices(apDevices, staDevices);
318 
319  // Add the IPv4 protocol stack to the nodes in our container
320  //
321  internet.Install(stas);
322  //
323  // Assign IPv4 addresses to the device drivers (actually to the associated
324  // IPv4 interfaces) we just created.
325  //
326  ipAddrs.Assign(infraDevices);
327  //
328  // Assign a new network prefix for each mobile network, according to
329  // the network mask initialized above
330  //
331  ipAddrs.NewNetwork();
332  //
333  // The new wireless nodes need a mobility model so we aggregate one
334  // to each of the nodes we just finished building.
335  //
336  Ptr<ListPositionAllocator> subnetAlloc = CreateObject<ListPositionAllocator>();
337  for (uint32_t j = 0; j < infra.GetN(); ++j)
338  {
339  subnetAlloc->Add(Vector(0.0, j, 0.0));
340  }
341  mobility.PushReferenceMobilityModel(backbone.Get(i));
342  mobility.SetPositionAllocator(subnetAlloc);
343  mobility.SetMobilityModel("ns3::RandomDirection2dMobilityModel",
344  "Bounds",
345  RectangleValue(Rectangle(-10, 10, -10, 10)),
346  "Speed",
347  StringValue("ns3::ConstantRandomVariable[Constant=3]"),
348  "Pause",
349  StringValue("ns3::ConstantRandomVariable[Constant=0.4]"));
350  mobility.Install(stas);
351  }
352 
354  // //
355  // Application configuration //
356  // //
358 
359  // Create the OnOff application to send UDP datagrams of size
360  // 210 bytes at a rate of 10 Kb/s, between two nodes
361  // We'll send data from the first wired LAN node on the first wired LAN
362  // to the last wireless STA on the last infrastructure net, thereby
363  // causing packets to traverse CSMA to adhoc to infrastructure links
364 
365  NS_LOG_INFO("Create Applications.");
366  uint16_t port = 9; // Discard port (RFC 863)
367 
368  // Let's make sure that the user does not define too few nodes
369  // to make this example work. We need lanNodes > 1 and infraNodes > 1
370  NS_ASSERT(lanNodes > 1 && infraNodes > 1);
371  // We want the source to be the first node created outside of the backbone
372  // Conveniently, the variable "backboneNodes" holds this node index value
373  Ptr<Node> appSource = NodeList::GetNode(backboneNodes);
374  // We want the sink to be the last node created in the topology.
375  uint32_t lastNodeIndex =
376  backboneNodes + backboneNodes * (lanNodes - 1) + backboneNodes * (infraNodes - 1) - 1;
377  Ptr<Node> appSink = NodeList::GetNode(lastNodeIndex);
378  // Let's fetch the IP address of the last node, which is on Ipv4Interface 1
379  Ipv4Address remoteAddr = appSink->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal();
380 
381  OnOffHelper onoff("ns3::UdpSocketFactory", Address(InetSocketAddress(remoteAddr, port)));
382 
383  ApplicationContainer apps = onoff.Install(appSource);
384  apps.Start(Seconds(3));
385  apps.Stop(Seconds(stopTime - 1));
386 
387  // Create a packet sink to receive these packets
388  PacketSinkHelper sink("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), port));
389  apps = sink.Install(appSink);
390  apps.Start(Seconds(3));
391 
393  // //
394  // Tracing configuration //
395  // //
397 
398  NS_LOG_INFO("Configure Tracing.");
400 
401  //
402  // Let's set up some ns-2-like ascii traces, using another helper class
403  //
404  AsciiTraceHelper ascii;
405  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream("mixed-wireless.tr");
406  wifiPhy.EnableAsciiAll(stream);
407  csma.EnableAsciiAll(stream);
408  internet.EnableAsciiIpv4All(stream);
409 
410  // Csma captures in non-promiscuous mode
411  csma.EnablePcapAll("mixed-wireless", false);
412  // pcap captures on the backbone wifi devices
413  wifiPhy.EnablePcap("mixed-wireless", backboneDevices, false);
414  // pcap trace on the application data sink
415  wifiPhy.EnablePcap("mixed-wireless", appSink->GetId(), 0);
416 
417  if (useCourseChangeCallback)
418  {
419  Config::Connect("/NodeList/*/$ns3::MobilityModel/CourseChange",
421  }
422 
423  AnimationInterface anim("mixed-wireless.xml");
424 
426  // //
427  // Run simulation //
428  // //
430 
431  NS_LOG_INFO("Run Simulation.");
433  Simulator::Run();
435 
436  return 0;
437 }
a polymophic address class
Definition: address.h:101
Interface to network animator.
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
void EnableAsciiAll(std::string prefix)
Enable ascii trace output on each device (which is of the appropriate type) in the set of all nodes c...
Manage ASCII trace files for device models.
Definition: trace-helper.h:174
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
Parse command-line arguments.
Definition: command-line.h:232
build a set of CsmaNetDevice objects
Definition: csma-helper.h:48
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4Address NewNetwork()
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetAny()
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
Helper class used to assign positions and mobility models to nodes.
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void SetMobilityModel(std::string type, Ts &&... args)
void PushReferenceMobilityModel(Ptr< Object > reference)
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t GetId() const
Definition: node.cc:117
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:251
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
Helper class that adds OLSR routing to nodes.
Definition: olsr-helper.h:42
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
a 2d rectangle
Definition: rectangle.h:35
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
Hold variables of type string.
Definition: string.h:56
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer::Iterator first, NodeContainer::Iterator last) const
Definition: wifi-helper.cc:756
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
void SetPcapDataLinkType(SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
Definition: wifi-helper.cc:543
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
Definition: wifi-helper.h:178
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
uint16_t port
Definition: dsdv-manet.cc:44
Time stopTime
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
AnimationInterface * anim
static void CourseChangeCallback(std::string path, Ptr< const MobilityModel > model)
This function will be used below as a trace sink, if the command-line argument or default value "useC...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Definition: olsr.py:1
csma
Definition: second.py:63
cmd
Definition: second.py:40
staDevices
Definition: third.py:100
ssid
Definition: third.py:93
mac
Definition: third.py:92
wifi
Definition: third.py:95
apDevices
Definition: third.py:103
mobility
Definition: third.py:105
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55