A Discrete-Event Network Simulator
API
wifi-spatial-reuse.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 University of Washington
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 //
22 // This example program can be used to experiment with spatial
23 // reuse mechanisms of 802.11ax.
24 //
25 // The geometry is as follows:
26 //
27 // STA1 STA1
28 // | |
29 // d1 | |d2
30 // | d3 |
31 // AP1 -----------AP2
32 //
33 // STA1 and AP1 are in one BSS (with color set to 1), while STA2 and AP2 are in
34 // another BSS (with color set to 2). The distances are configurable (d1 through d3).
35 //
36 // STA1 is continously transmitting data to AP1, while STA2 is continuously sending data to AP2.
37 // Each STA has configurable traffic loads (inter packet interval and packet size).
38 // It is also possible to configure TX power per node as well as their CCA-ED tresholds.
39 // OBSS_PD spatial reuse feature can be enabled (default) or disabled, and the OBSS_PD
40 // threshold can be set as well (default: -72 dBm).
41 // A simple Friis path loss model is used and a constant PHY rate is considered.
42 //
43 // In general, the program can be configured at run-time by passing command-line arguments.
44 // The following command will display all of the available run-time help options:
45 // ./waf --run "wifi-spatial-reuse --help"
46 //
47 // By default, the script shows the benefit of the OBSS_PD spatial reuse script:
48 // ./waf --run wifi-spatial-reuse
49 // Throughput for BSS 1: 6.6468 Mbit/s
50 // Throughput for BSS 2: 6.6672 Mbit/s
51 //
52 // If one disables the OBSS_PD feature, a lower throughput is obtained per BSS:
53 // ./waf --run "wifi-spatial-reuse --enableObssPd=0"
54 // Throughput for BSS 1: 5.8692 Mbit/s
55 // Throughput for BSS 2: 5.9364 Mbit/
56 //
57 // This difference between those results is because OBSS_PD spatial
58 // enables to ignore transmissions from another BSS when the received power
59 // is below the configured threshold, and therefore either defer during ongoing
60 // transmission or transmit at the same time.
61 //
62 
63 #include "ns3/command-line.h"
64 #include "ns3/config.h"
65 #include "ns3/string.h"
66 #include "ns3/spectrum-wifi-helper.h"
67 #include "ns3/ssid.h"
68 #include "ns3/mobility-helper.h"
69 #include "ns3/application-container.h"
70 #include "ns3/multi-model-spectrum-channel.h"
71 #include "ns3/wifi-net-device.h"
72 #include "ns3/ap-wifi-mac.h"
73 #include "ns3/he-configuration.h"
74 #include "ns3/packet-socket-helper.h"
75 #include "ns3/packet-socket-client.h"
76 #include "ns3/packet-socket-server.h"
77 
78 using namespace ns3;
79 
80 std::vector<uint32_t> bytesReceived (4);
81 
82 uint32_t
83 ContextToNodeId (std::string context)
84 {
85  std::string sub = context.substr (10);
86  uint32_t pos = sub.find ("/Device");
87  return atoi (sub.substr (0, pos).c_str ());
88 }
89 
90 void
91 SocketRx (std::string context, Ptr<const Packet> p, const Address &addr)
92 {
93  uint32_t nodeId = ContextToNodeId (context);
94  bytesReceived[nodeId] += p->GetSize ();
95 }
96 
97 int
98 main (int argc, char *argv[])
99 {
100  double duration = 10.0; // seconds
101  double d1 = 30.0; // meters
102  double d2 = 30.0; // meters
103  double d3 = 150.0; // meters
104  double powSta1 = 10.0; // dBm
105  double powSta2 = 10.0; // dBm
106  double powAp1 = 21.0; // dBm
107  double powAp2 = 21.0; // dBm
108  double ccaEdTrSta1 = -62; // dBm
109  double ccaEdTrSta2 = -62; // dBm
110  double ccaEdTrAp1 = -62; // dBm
111  double ccaEdTrAp2 = -62; // dBm
112  uint32_t payloadSize = 1500; // bytes
113  uint32_t mcs = 0; // MCS value
114  double interval = 0.001; // seconds
115  bool enableObssPd = true;
116  double obssPdThreshold = -72.0; // dBm
117 
118  CommandLine cmd (__FILE__);
119  cmd.AddValue ("duration", "Duration of simulation (s)", duration);
120  cmd.AddValue ("interval", "Inter packet interval (s)", interval);
121  cmd.AddValue ("enableObssPd", "Enable/disable OBSS_PD", enableObssPd);
122  cmd.AddValue ("d1", "Distance between STA1 and AP1 (m)", d1);
123  cmd.AddValue ("d2", "Distance between STA2 and AP2 (m)", d2);
124  cmd.AddValue ("d3", "Distance between AP1 and AP2 (m)", d3);
125  cmd.AddValue ("powSta1", "Power of STA1 (dBm)", powSta1);
126  cmd.AddValue ("powSta2", "Power of STA2 (dBm)", powSta2);
127  cmd.AddValue ("powAp1", "Power of AP1 (dBm)", powAp1);
128  cmd.AddValue ("powAp2", "Power of AP2 (dBm)", powAp2);
129  cmd.AddValue ("ccaEdTrSta1", "CCA-ED Threshold of STA1 (dBm)", ccaEdTrSta1);
130  cmd.AddValue ("ccaEdTrSta2", "CCA-ED Threshold of STA2 (dBm)", ccaEdTrSta2);
131  cmd.AddValue ("ccaEdTrAp1", "CCA-ED Threshold of AP1 (dBm)", ccaEdTrAp1);
132  cmd.AddValue ("ccaEdTrAp2", "CCA-ED Threshold of AP2 (dBm)", ccaEdTrAp2);
133  cmd.AddValue ("mcs", "The constant MCS value to transmit HE PPDUs", mcs);
134  cmd.Parse (argc, argv);
135 
137  wifiStaNodes.Create (2);
138 
139  NodeContainer wifiApNodes;
140  wifiApNodes.Create (2);
141 
142  SpectrumWifiPhyHelper spectrumPhy;
143  Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
144  Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
145  spectrumChannel->AddPropagationLossModel (lossModel);
146  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
147  spectrumChannel->SetPropagationDelayModel (delayModel);
148 
149  spectrumPhy.SetChannel (spectrumChannel);
150  spectrumPhy.SetErrorRateModel ("ns3::YansErrorRateModel");
151  spectrumPhy.Set ("Frequency", UintegerValue (5180)); // channel 36 at 20 MHz
152  spectrumPhy.SetPreambleDetectionModel ("ns3::ThresholdPreambleDetectionModel");
153  //TODO: add parameter to configure CCA-PD
154 
156  wifi.SetStandard (WIFI_STANDARD_80211ax_5GHZ);
157  if (enableObssPd)
158  {
159  wifi.SetObssPdAlgorithm ("ns3::ConstantObssPdAlgorithm",
160  "ObssPdLevel", DoubleValue (obssPdThreshold));
161  }
162 
164  std::ostringstream oss;
165  oss << "HeMcs" << mcs;
166  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
167  "DataMode", StringValue (oss.str ()),
168  "ControlMode", StringValue (oss.str ()));
169 
170  spectrumPhy.Set ("TxPowerStart", DoubleValue (powSta1));
171  spectrumPhy.Set ("TxPowerEnd", DoubleValue (powSta1));
172  spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrSta1));
173  spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
174 
175  Ssid ssidA = Ssid ("A");
176  mac.SetType ("ns3::StaWifiMac",
177  "Ssid", SsidValue (ssidA));
178  NetDeviceContainer staDeviceA = wifi.Install (spectrumPhy, mac, wifiStaNodes.Get (0));
179 
180  spectrumPhy.Set ("TxPowerStart", DoubleValue (powAp1));
181  spectrumPhy.Set ("TxPowerEnd", DoubleValue (powAp1));
182  spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrAp1));
183  spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
184 
185  mac.SetType ("ns3::ApWifiMac",
186  "Ssid", SsidValue (ssidA));
187  NetDeviceContainer apDeviceA = wifi.Install (spectrumPhy, mac, wifiApNodes.Get (0));
188 
189  Ptr<WifiNetDevice> apDevice = apDeviceA.Get (0)->GetObject<WifiNetDevice> ();
190  Ptr<ApWifiMac> apWifiMac = apDevice->GetMac ()->GetObject<ApWifiMac> ();
191  if (enableObssPd)
192  {
193  apDevice->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (1));
194  }
195 
196  spectrumPhy.Set ("TxPowerStart", DoubleValue (powSta2));
197  spectrumPhy.Set ("TxPowerEnd", DoubleValue (powSta2));
198  spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrSta2));
199  spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
200 
201  Ssid ssidB = Ssid ("B");
202  mac.SetType ("ns3::StaWifiMac",
203  "Ssid", SsidValue (ssidB));
204  NetDeviceContainer staDeviceB = wifi.Install (spectrumPhy, mac, wifiStaNodes.Get (1));
205 
206  spectrumPhy.Set ("TxPowerStart", DoubleValue (powAp2));
207  spectrumPhy.Set ("TxPowerEnd", DoubleValue (powAp2));
208  spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrAp2));
209  spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
210 
211  mac.SetType ("ns3::ApWifiMac",
212  "Ssid", SsidValue (ssidB));
213  NetDeviceContainer apDeviceB = wifi.Install (spectrumPhy, mac, wifiApNodes.Get (1));
214 
215  Ptr<WifiNetDevice> ap2Device = apDeviceB.Get (0)->GetObject<WifiNetDevice> ();
216  apWifiMac = ap2Device->GetMac ()->GetObject<ApWifiMac> ();
217  if (enableObssPd)
218  {
219  ap2Device->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (2));
220  }
221 
223  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
224  positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // AP1
225  positionAlloc->Add (Vector (d3, 0.0, 0.0)); // AP2
226  positionAlloc->Add (Vector (0.0, d1, 0.0)); // STA1
227  positionAlloc->Add (Vector (d3, d2, 0.0)); // STA2
228  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
229  mobility.SetPositionAllocator (positionAlloc);
230  mobility.Install (wifiApNodes);
231  mobility.Install (wifiStaNodes);
232 
233  PacketSocketHelper packetSocket;
234  packetSocket.Install (wifiApNodes);
235  packetSocket.Install (wifiStaNodes);
237  TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
238 
239  //BSS 1
240  {
241  PacketSocketAddress socketAddr;
242  socketAddr.SetSingleDevice (staDeviceA.Get (0)->GetIfIndex ());
243  socketAddr.SetPhysicalAddress (apDeviceA.Get (0)->GetAddress ());
244  socketAddr.SetProtocol (1);
245  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
246  client->SetRemote (socketAddr);
247  wifiStaNodes.Get (0)->AddApplication (client);
248  client->SetAttribute ("PacketSize", UintegerValue (payloadSize));
249  client->SetAttribute ("MaxPackets", UintegerValue (0));
250  client->SetAttribute ("Interval", TimeValue (Seconds (interval)));
251  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
252  server->SetLocal (socketAddr);
253  wifiApNodes.Get (0)->AddApplication (server);
254  }
255 
256  // BSS 2
257  {
258  PacketSocketAddress socketAddr;
259  socketAddr.SetSingleDevice (staDeviceB.Get (0)->GetIfIndex ());
260  socketAddr.SetPhysicalAddress (apDeviceB.Get (0)->GetAddress ());
261  socketAddr.SetProtocol (1);
262  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
263  client->SetRemote (socketAddr);
264  wifiStaNodes.Get (1)->AddApplication (client);
265  client->SetAttribute ("PacketSize", UintegerValue (payloadSize));
266  client->SetAttribute ("MaxPackets", UintegerValue (0));
267  client->SetAttribute ("Interval", TimeValue (Seconds (interval)));
268  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
269  server->SetLocal (socketAddr);
270  wifiApNodes.Get (1)->AddApplication (server);
271  }
272 
273  Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSocketServer/Rx", MakeCallback (&SocketRx));
274 
275  Simulator::Stop (Seconds (duration));
276  Simulator::Run ();
277 
279 
280  for (uint32_t i = 0; i < 2; i++)
281  {
282  double throughput = static_cast<double> (bytesReceived[2 + i]) * 8 / 1000 / 1000 / duration;
283  std::cout << "Throughput for BSS " << i + 1 << ": " << throughput << " Mbit/s" << std::endl;
284  }
285 
286  return 0;
287 }
a polymophic address class
Definition: address.h:91
Wi-Fi AP state machine.
Definition: ap-wifi-mac.h:51
holds a vector of ns3::Application pointers.
Parse command-line arguments.
Definition: command-line.h:229
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
virtual Address GetAddress(void) const =0
virtual uint32_t GetIfIndex(void) const =0
keep track of a set of node pointers.
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 AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:105
Hold variables of type string.
Definition: string.h:41
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:829
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:274
create MAC layers for a ns3::WifiNetDevice.
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac(void) const
Ptr< HeConfiguration > GetHeConfiguration(void) const
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:154
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
Definition: wifi-helper.h:440
void SetPreambleDetectionModel(std::string type, Args &&... args)
Helper function used to set the preamble detection model.
Definition: wifi-helper.h:456
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
cmd
Definition: second.py:35
mac
Definition: third.py:99
wifi
Definition: third.py:96
mobility
Definition: third.py:108
wifiStaNodes
Definition: third.py:88
uint32_t ContextToNodeId(std::string context)
std::vector< uint32_t > bytesReceived(4)
void SocketRx(std::string context, Ptr< const Packet > p, const Address &addr)