A Discrete-Event Network Simulator
API
80211e-txop.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 Sébastien Deronne
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 #include "ns3/command-line.h"
22 #include "ns3/string.h"
23 #include "ns3/pointer.h"
24 #include "ns3/log.h"
25 #include "ns3/yans-wifi-helper.h"
26 #include "ns3/ssid.h"
27 #include "ns3/mobility-helper.h"
28 #include "ns3/internet-stack-helper.h"
29 #include "ns3/ipv4-address-helper.h"
30 #include "ns3/udp-client-server-helper.h"
31 #include "ns3/on-off-helper.h"
32 #include "ns3/yans-wifi-channel.h"
33 #include "ns3/wifi-net-device.h"
34 #include "ns3/qos-txop.h"
35 #include "ns3/wifi-mac.h"
36 
37 // This is an example that illustrates 802.11 QoS for different Access Categories.
38 // It defines 4 independent Wi-Fi networks (working on different logical channels
39 // on the same "ns3::YansWifiPhy" channel object).
40 // Each network contains one access point and one station. Each station continuously
41 // transmits data packets to its respective AP.
42 //
43 // Network topology (numbers in parentheses are channel numbers):
44 //
45 // BSS A (36) BSS B (40) BSS C (44) BSS D (48)
46 // * * * * * * * *
47 // | | | | | | | |
48 // AP A STA A AP B STA B AP C STA C AP D STA D
49 //
50 // The configuration is the following on the 4 networks:
51 // - STA A sends AC_BE traffic to AP A with default AC_BE TXOP value of 0 (1 MSDU);
52 // - STA B sends AC_BE traffic to AP B with non-default AC_BE TXOP of 3.008 ms;
53 // - STA C sends AC_VI traffic to AP C with default AC_VI TXOP of 3.008 ms;
54 // - STA D sends AC_VI traffic to AP D with non-default AC_VI TXOP value of 0 (1 MSDU);
55 //
56 // The user can select the distance between the stations and the APs, can enable/disable the RTS/CTS mechanism
57 // and can choose the payload size and the simulation duration.
58 // Example: ./waf --run "80211e-txop --distance=10 --simulationTime=20 --payloadSize=1000"
59 //
60 // The output prints the throughput measured for the 4 cases/networks described above. When TXOP is enabled, results show
61 // increased throughput since the channel is granted for a longer duration. TXOP is enabled by default for AC_VI and AC_VO,
62 // so that they can use the channel for a longer duration than AC_BE and AC_BK.
63 
64 using namespace ns3;
65 
66 NS_LOG_COMPONENT_DEFINE ("80211eTxop");
67 
68 int main (int argc, char *argv[])
69 {
70  uint32_t payloadSize = 1472; //bytes
71  double simulationTime = 10; //seconds
72  double distance = 5; //meters
73  bool enablePcap = 0;
74  bool verifyResults = 0; //used for regression
75 
77  cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize);
78  cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
79  cmd.AddValue ("distance", "Distance in meters between the station and the access point", distance);
80  cmd.AddValue ("enablePcap", "Enable/disable pcap file generation", enablePcap);
81  cmd.AddValue ("verifyResults", "Enable/disable results verification at the end of the simulation", verifyResults);
82  cmd.Parse (argc, argv);
83 
85  wifiStaNodes.Create (4);
86  NodeContainer wifiApNodes;
87  wifiApNodes.Create (4);
88 
91  phy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
92  phy.SetChannel (channel.Create ());
93 
94  WifiHelper wifi; //the default standard of 802.11a will be selected by this helper since the program doesn't specify another one
95  wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
97 
98  NetDeviceContainer staDeviceA, staDeviceB, staDeviceC, staDeviceD, apDeviceA, apDeviceB, apDeviceC, apDeviceD;
99  Ssid ssid;
100 
101  //Network A
102  ssid = Ssid ("network-A");
103  phy.Set ("ChannelNumber", UintegerValue (36));
104  mac.SetType ("ns3::StaWifiMac",
105  "QosSupported", BooleanValue (true),
106  "Ssid", SsidValue (ssid));
107  staDeviceA = wifi.Install (phy, mac, wifiStaNodes.Get (0));
108 
109  mac.SetType ("ns3::ApWifiMac",
110  "QosSupported", BooleanValue (true),
111  "Ssid", SsidValue (ssid),
112  "EnableBeaconJitter", BooleanValue (false));
113  apDeviceA = wifi.Install (phy, mac, wifiApNodes.Get (0));
114 
115  //Network B
116  ssid = Ssid ("network-B");
117  phy.Set ("ChannelNumber", UintegerValue (40));
118  mac.SetType ("ns3::StaWifiMac",
119  "QosSupported", BooleanValue (true),
120  "Ssid", SsidValue (ssid));
121 
122  staDeviceB = wifi.Install (phy, mac, wifiStaNodes.Get (1));
123 
124  mac.SetType ("ns3::ApWifiMac",
125  "QosSupported", BooleanValue (true),
126  "Ssid", SsidValue (ssid),
127  "EnableBeaconJitter", BooleanValue (false));
128  apDeviceB = wifi.Install (phy, mac, wifiApNodes.Get (1));
129 
130  //Modify EDCA configuration (TXOP limit) for AC_BE
131  Ptr<NetDevice> dev = wifiApNodes.Get (1)->GetDevice (0);
132  Ptr<WifiNetDevice> wifi_dev = DynamicCast<WifiNetDevice> (dev);
133  Ptr<WifiMac> wifi_mac = wifi_dev->GetMac ();
134  PointerValue ptr;
135  Ptr<QosTxop> edca;
136  wifi_mac->GetAttribute ("BE_Txop", ptr);
137  edca = ptr.Get<QosTxop> ();
138  edca->SetTxopLimit (MicroSeconds (3008));
139 
140  //Network C
141  ssid = Ssid ("network-C");
142  phy.Set ("ChannelNumber", UintegerValue (44));
143  mac.SetType ("ns3::StaWifiMac",
144  "QosSupported", BooleanValue (true),
145  "Ssid", SsidValue (ssid));
146 
147  staDeviceC = wifi.Install (phy, mac, wifiStaNodes.Get (2));
148 
149  mac.SetType ("ns3::ApWifiMac",
150  "QosSupported", BooleanValue (true),
151  "Ssid", SsidValue (ssid),
152  "EnableBeaconJitter", BooleanValue (false));
153  apDeviceC = wifi.Install (phy, mac, wifiApNodes.Get (2));
154 
155  //Network D
156  ssid = Ssid ("network-D");
157  phy.Set ("ChannelNumber", UintegerValue (48));
158  mac.SetType ("ns3::StaWifiMac",
159  "QosSupported", BooleanValue (true),
160  "Ssid", SsidValue (ssid));
161 
162  staDeviceD = wifi.Install (phy, mac, wifiStaNodes.Get (3));
163 
164  mac.SetType ("ns3::ApWifiMac",
165  "QosSupported", BooleanValue (true),
166  "Ssid", SsidValue (ssid),
167  "EnableBeaconJitter", BooleanValue (false));
168  apDeviceD = wifi.Install (phy, mac, wifiApNodes.Get (3));
169 
170  //Modify EDCA configuration (TXOP limit) for AC_VO
171  dev = wifiApNodes.Get (3)->GetDevice (0);
172  wifi_dev = DynamicCast<WifiNetDevice> (dev);
173  wifi_mac = wifi_dev->GetMac ();
174  wifi_mac->GetAttribute ("VI_Txop", ptr);
175  edca = ptr.Get<QosTxop> ();
176  edca->SetTxopLimit (MicroSeconds (0));
177 
178  /* Setting mobility model */
180  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
181  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
182 
183  //Set position for APs
184  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
185  positionAlloc->Add (Vector (10.0, 0.0, 0.0));
186  positionAlloc->Add (Vector (20.0, 0.0, 0.0));
187  positionAlloc->Add (Vector (30.0, 0.0, 0.0));
188  //Set position for STAs
189  positionAlloc->Add (Vector (distance, 0.0, 0.0));
190  positionAlloc->Add (Vector (10 + distance, 0.0, 0.0));
191  positionAlloc->Add (Vector (20 + distance, 0.0, 0.0));
192  positionAlloc->Add (Vector (30 + distance, 0.0, 0.0));
193  //Remark: while we set these positions 10 meters apart, the networks do not interact
194  //and the only variable that affects transmission performance is the distance.
195 
196  mobility.SetPositionAllocator (positionAlloc);
197  mobility.Install (wifiApNodes);
198  mobility.Install (wifiStaNodes);
199 
200  /* Internet stack */
202  stack.Install (wifiApNodes);
203  stack.Install (wifiStaNodes);
204 
206  address.SetBase ("192.168.1.0", "255.255.255.0");
207  Ipv4InterfaceContainer StaInterfaceA;
208  StaInterfaceA = address.Assign (staDeviceA);
209  Ipv4InterfaceContainer ApInterfaceA;
210  ApInterfaceA = address.Assign (apDeviceA);
211 
212  address.SetBase ("192.168.2.0", "255.255.255.0");
213  Ipv4InterfaceContainer StaInterfaceB;
214  StaInterfaceB = address.Assign (staDeviceB);
215  Ipv4InterfaceContainer ApInterfaceB;
216  ApInterfaceB = address.Assign (apDeviceB);
217 
218  address.SetBase ("192.168.3.0", "255.255.255.0");
219  Ipv4InterfaceContainer StaInterfaceC;
220  StaInterfaceC = address.Assign (staDeviceC);
221  Ipv4InterfaceContainer ApInterfaceC;
222  ApInterfaceC = address.Assign (apDeviceC);
223 
224  address.SetBase ("192.168.4.0", "255.255.255.0");
225  Ipv4InterfaceContainer StaInterfaceD;
226  StaInterfaceD = address.Assign (staDeviceD);
227  Ipv4InterfaceContainer ApInterfaceD;
228  ApInterfaceD = address.Assign (apDeviceD);
229 
230  /* Setting applications */
231  uint16_t port = 5001;
232  UdpServerHelper serverA (port);
233  ApplicationContainer serverAppA = serverA.Install (wifiApNodes.Get (0));
234  serverAppA.Start (Seconds (0.0));
235  serverAppA.Stop (Seconds (simulationTime + 1));
236 
237  InetSocketAddress destA (ApInterfaceA.GetAddress (0), port);
238  destA.SetTos (0x70); //AC_BE
239 
240  OnOffHelper clientA ("ns3::UdpSocketFactory", destA);
241  clientA.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
242  clientA.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
243  clientA.SetAttribute ("DataRate", StringValue ("100000kb/s"));
244  clientA.SetAttribute ("PacketSize", UintegerValue (payloadSize));
245 
246  ApplicationContainer clientAppA = clientA.Install (wifiStaNodes.Get (0));
247  clientAppA.Start (Seconds (1.0));
248  clientAppA.Stop (Seconds (simulationTime + 1));
249 
250  UdpServerHelper serverB (port);
251  ApplicationContainer serverAppB = serverB.Install (wifiApNodes.Get (1));
252  serverAppB.Start (Seconds (0.0));
253  serverAppB.Stop (Seconds (simulationTime + 1));
254 
255  InetSocketAddress destB (ApInterfaceB.GetAddress (0), port);
256  destB.SetTos (0x70); //AC_BE
257 
258  OnOffHelper clientB ("ns3::UdpSocketFactory", destB);
259  clientB.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
260  clientB.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
261  clientB.SetAttribute ("DataRate", StringValue ("100000kb/s"));
262  clientB.SetAttribute ("PacketSize", UintegerValue (payloadSize));
263 
264  ApplicationContainer clientAppB = clientB.Install (wifiStaNodes.Get (1));
265  clientAppB.Start (Seconds (1.0));
266  clientAppB.Stop (Seconds (simulationTime + 1));
267 
268  UdpServerHelper serverC (port);
269  ApplicationContainer serverAppC = serverC.Install (wifiApNodes.Get (2));
270  serverAppC.Start (Seconds (0.0));
271  serverAppC.Stop (Seconds (simulationTime + 1));
272 
273  InetSocketAddress destC (ApInterfaceC.GetAddress (0), port);
274  destC.SetTos (0xb8); //AC_VI
275 
276  OnOffHelper clientC ("ns3::UdpSocketFactory", destC);
277  clientC.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
278  clientC.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
279  clientC.SetAttribute ("DataRate", StringValue ("100000kb/s"));
280  clientC.SetAttribute ("PacketSize", UintegerValue (payloadSize));
281 
282  ApplicationContainer clientAppC = clientC.Install (wifiStaNodes.Get (2));
283  clientAppC.Start (Seconds (1.0));
284  clientAppC.Stop (Seconds (simulationTime + 1));
285 
286  UdpServerHelper serverD (port);
287  ApplicationContainer serverAppD = serverD.Install (wifiApNodes.Get (3));
288  serverAppD.Start (Seconds (0.0));
289  serverAppD.Stop (Seconds (simulationTime + 1));
290 
291  InetSocketAddress destD (ApInterfaceD.GetAddress (0), port);
292  destD.SetTos (0xb8); //AC_VI
293 
294  OnOffHelper clientD ("ns3::UdpSocketFactory", destD);
295  clientD.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
296  clientD.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
297  clientD.SetAttribute ("DataRate", StringValue ("100000kb/s"));
298  clientD.SetAttribute ("PacketSize", UintegerValue (payloadSize));
299 
300  ApplicationContainer clientAppD = clientD.Install (wifiStaNodes.Get (3));
301  clientAppD.Start (Seconds (1.0));
302  clientAppD.Stop (Seconds (simulationTime + 1));
303 
304  if (enablePcap)
305  {
306  phy.EnablePcap ("AP_A", apDeviceA.Get (0));
307  phy.EnablePcap ("STA_A", staDeviceA.Get (0));
308  phy.EnablePcap ("AP_B", apDeviceB.Get (0));
309  phy.EnablePcap ("STA_B", staDeviceB.Get (0));
310  phy.EnablePcap ("AP_C", apDeviceC.Get (0));
311  phy.EnablePcap ("STA_C", staDeviceC.Get (0));
312  phy.EnablePcap ("AP_D", apDeviceD.Get (0));
313  phy.EnablePcap ("STA_D", staDeviceD.Get (0));
314  }
315 
316  Simulator::Stop (Seconds (simulationTime + 1));
317  Simulator::Run ();
318 
319  /* Show results */
320  uint64_t totalPacketsThroughA = DynamicCast<UdpServer> (serverAppA.Get (0))->GetReceived ();
321  uint64_t totalPacketsThroughB = DynamicCast<UdpServer> (serverAppB.Get (0))->GetReceived ();
322  uint64_t totalPacketsThroughC = DynamicCast<UdpServer> (serverAppC.Get (0))->GetReceived ();
323  uint64_t totalPacketsThroughD = DynamicCast<UdpServer> (serverAppD.Get (0))->GetReceived ();
324 
326 
327  double throughput = totalPacketsThroughA * payloadSize * 8 / (simulationTime * 1000000.0);
328  std::cout << "Throughput for AC_BE with default TXOP limit (0ms): " << throughput << " Mbit/s" << '\n';
329  if (verifyResults && (throughput < 28 || throughput > 29))
330  {
331  NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
332  exit (1);
333  }
334 
335  throughput = totalPacketsThroughB * payloadSize * 8 / (simulationTime * 1000000.0);
336  std::cout << "Throughput for AC_BE with non-default TXOP limit (3.008ms): " << throughput << " Mbit/s" << '\n';
337  if (verifyResults && (throughput < 35.5 || throughput > 36.5))
338  {
339  NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
340  exit (1);
341  }
342 
343  throughput = totalPacketsThroughC * payloadSize * 8 / (simulationTime * 1000000.0);
344  std::cout << "Throughput for AC_VI with default TXOP limit (3.008ms): " << throughput << " Mbit/s" << '\n';
345  if (verifyResults && (throughput < 36 || throughput > 37))
346  {
347  NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
348  exit (1);
349  }
350 
351  throughput = totalPacketsThroughD * payloadSize * 8 / (simulationTime * 1000000.0);
352  std::cout << "Throughput for AC_VI with non-default TXOP limit (0ms): " << throughput << " Mbit/s" << '\n';
353  if (verifyResults && (throughput < 31.5 || throughput > 32.5))
354  {
355  NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
356  exit (1);
357  }
358 
359  return 0;
360 }
holds a vector of ns3::Application pointers.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
an Inet address class
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:36
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Hold variables of type string.
Definition: string.h:41
Make it easy to create and manage PHY objects for the yans model.
static YansWifiChannelHelper Default(void)
Create a channel helper in a default working state.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
bool enablePcap
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:90
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
aggregate IP/TCP/UDP functionality to existing Nodes.
cmd
Definition: second.py:35
static YansWifiPhyHelper Default(void)
Create a phy helper in a default working state.
helps to create WifiNetDevice objects
Definition: wifi-helper.h:230
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:42
stack
Definition: first.py:34
uint16_t port
Definition: dsdv-manet.cc:45
channel
Definition: third.py:85
mobility
Definition: third.py:101
phy
Definition: third.py:86
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Hold an unsigned integer type.
Definition: uinteger.h:44
ssid
Definition: third.py:93
holds a vector of ns3::NetDevice pointers
mac
Definition: third.py:92
Create a server application which waits for input UDP packets and uses the information carried into t...
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
Parse command-line arguments.
Definition: command-line.h:213
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
address
Definition: first.py:37
manage and create wifi channel objects for the yans model.
create MAC layers for a ns3::WifiNetDevice.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
wifi
Definition: third.py:89
Helper class used to assign positions and mobility models to nodes.
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
Ptr< WifiMac > GetMac(void) const
void SetTxopLimit(Time txopLimit)
Set the TXOP limit.
Definition: txop.cc:264
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
AttributeValue implementation for Ssid.
Definition: ssid.h:110
Ptr< T > Get(void) const
Definition: pointer.h:194
void Add(Vector v)
Add a position to the list of positions.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1030
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
wifiStaNodes
Definition: third.py:81
Include Radiotap link layer information.
Definition: wifi-helper.h:111
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:223
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.