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// ./ns3 run "wifi-spatial-reuse --help"
46//
47// According to the Wi-Fi models of ns-3.36 release, throughput with
48// OBSS PD enabled (--enableObssPd=True) was roughly 6.5 Mbps, and with
49// it disabled (--enableObssPd=False) was roughly 3.5 Mbps.
50//
51// This difference between those results is because OBSS_PD spatial
52// reuse enables to ignore transmissions from another BSS when the
53// received power is below the configured threshold, and therefore
54// either defer during ongoing transmission or transmit at the same
55// time.
56//
57// Note that, by default, this script configures a network using a
58// channel bandwidth of 20 MHz. Changing this value alone (through
59// the --channelWidth argument) without properly adjusting other
60// parameters will void the effect of spatial reuse: since energy is
61// measured over the 20 MHz primary channel regardless of the channel
62// width, doubling the transmission bandwidth creates a 3 dB drop in
63// the measured energy level (i.e., a halving of the measured
64// energy). Because of this, when using the channelWidth argument
65// users should also adjust the CCA-ED Thresholds (via --ccaEdTrSta1,
66// --ccaEdTrSta2, --ccaEdTrAp1, and --ccaEdTrAp2), the Minimum RSSI
67// for preamble detection (via --minimumRssi), and the OBSS PD
68// Threshold (via --obssPdThreshold) appropriately. For instance,
69// this can be accomplished for a channel width of 40 MHz by lowering
70// all these values by 3 dB compared to their defaults.
71//
72// In addition, consider that adapting the adjustments shown above
73// for an 80 MHz bandwidth (using a 6 dB threshold adjustment instead
74// of 3 dB) will not produce any changes when enableObssPd is enabled
75// or disabled. The cause for this is the insufficient amount of
76// traffic that is generated by default in the example: increasing
77// the bandwidth shortens the frame durations, and lowers the
78// collision probability. Collisions between BSSs are a necessary
79// condition to see the improvements brought by spatial reuse, and
80// thus increasing the amount of generated traffic by setting the
81// interval argument to a lower value is necessary to see the
82// benefits of spatial reuse in this scenario. This can, for
83// instance, be accomplished by setting --interval=0.0001.
84//
85
86#include "ns3/abort.h"
87#include "ns3/command-line.h"
88#include "ns3/config.h"
89#include "ns3/string.h"
90#include "ns3/double.h"
91#include "ns3/spectrum-wifi-helper.h"
92#include "ns3/ssid.h"
93#include "ns3/mobility-helper.h"
94#include "ns3/application-container.h"
95#include "ns3/multi-model-spectrum-channel.h"
96#include "ns3/wifi-net-device.h"
97#include "ns3/ap-wifi-mac.h"
98#include "ns3/he-configuration.h"
99#include "ns3/packet-socket-helper.h"
100#include "ns3/packet-socket-client.h"
101#include "ns3/packet-socket-server.h"
102
103using namespace ns3;
104
105std::vector<uint32_t> bytesReceived (4);
106
108ContextToNodeId (std::string context)
109{
110 std::string sub = context.substr (10);
111 uint32_t pos = sub.find ("/Device");
112 return atoi (sub.substr (0, pos).c_str ());
113}
114
115void
116SocketRx (std::string context, Ptr<const Packet> p, const Address &addr)
117{
118 uint32_t nodeId = ContextToNodeId (context);
119 bytesReceived[nodeId] += p->GetSize ();
120}
121
122int
123main (int argc, char *argv[])
124{
125 double duration = 10.0; // seconds
126 double d1 = 30.0; // meters
127 double d2 = 30.0; // meters
128 double d3 = 150.0; // meters
129 double powSta1 = 10.0; // dBm
130 double powSta2 = 10.0; // dBm
131 double powAp1 = 21.0; // dBm
132 double powAp2 = 21.0; // dBm
133 double ccaEdTrSta1 = -62; // dBm
134 double ccaEdTrSta2 = -62; // dBm
135 double ccaEdTrAp1 = -62; // dBm
136 double ccaEdTrAp2 = -62; // dBm
137 double minimumRssi = -82; // dBm
138 int channelBandwidth = 20; // MHz
139 uint32_t payloadSize = 1500; // bytes
140 uint32_t mcs = 0; // MCS value
141 double interval = 0.001; // seconds
142 bool enableObssPd = true;
143 double obssPdThreshold = -72.0; // dBm
144
145 CommandLine cmd (__FILE__);
146 cmd.AddValue ("duration", "Duration of simulation (s)", duration);
147 cmd.AddValue ("interval", "Inter packet interval (s)", interval);
148 cmd.AddValue ("enableObssPd", "Enable/disable OBSS_PD", enableObssPd);
149 cmd.AddValue ("d1", "Distance between STA1 and AP1 (m)", d1);
150 cmd.AddValue ("d2", "Distance between STA2 and AP2 (m)", d2);
151 cmd.AddValue ("d3", "Distance between AP1 and AP2 (m)", d3);
152 cmd.AddValue ("powSta1", "Power of STA1 (dBm)", powSta1);
153 cmd.AddValue ("powSta2", "Power of STA2 (dBm)", powSta2);
154 cmd.AddValue ("powAp1", "Power of AP1 (dBm)", powAp1);
155 cmd.AddValue ("powAp2", "Power of AP2 (dBm)", powAp2);
156 cmd.AddValue ("ccaEdTrSta1", "CCA-ED Threshold of STA1 (dBm)", ccaEdTrSta1);
157 cmd.AddValue ("ccaEdTrSta2", "CCA-ED Threshold of STA2 (dBm)", ccaEdTrSta2);
158 cmd.AddValue ("ccaEdTrAp1", "CCA-ED Threshold of AP1 (dBm)", ccaEdTrAp1);
159 cmd.AddValue ("ccaEdTrAp2", "CCA-ED Threshold of AP2 (dBm)", ccaEdTrAp2);
160 cmd.AddValue ("minimumRssi", "Minimum RSSI for the ThresholdPreambleDetectionModel", minimumRssi);
161 cmd.AddValue ("channelBandwidth", "Bandwidth of the channel in MHz [20, 40, or 80]", channelBandwidth);
162 cmd.AddValue ("obssPdThreshold", "Threshold for the OBSS PD Algorithm", obssPdThreshold);
163 cmd.AddValue ("mcs", "The constant MCS value to transmit HE PPDUs", mcs);
164 cmd.Parse (argc, argv);
165
167 wifiStaNodes.Create (2);
168
169 NodeContainer wifiApNodes;
170 wifiApNodes.Create (2);
171
172 SpectrumWifiPhyHelper spectrumPhy;
173 Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
174 Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
175 spectrumChannel->AddPropagationLossModel (lossModel);
176 Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
177 spectrumChannel->SetPropagationDelayModel (delayModel);
178
179 spectrumPhy.SetChannel (spectrumChannel);
180 spectrumPhy.SetErrorRateModel ("ns3::YansErrorRateModel");
181 switch (channelBandwidth)
182 {
183 case 20:
184 spectrumPhy.Set ("ChannelSettings", StringValue ("{36, 20, BAND_5GHZ, 0}"));
185 break;
186 case 40:
187 spectrumPhy.Set ("ChannelSettings", StringValue ("{62, 40, BAND_5GHZ, 0}"));
188 break;
189 case 80:
190 spectrumPhy.Set ("ChannelSettings", StringValue ("{171, 80, BAND_5GHZ, 0}"));
191 break;
192 default:
193 NS_ABORT_MSG ("Unrecognized channel bandwidth: " << channelBandwidth);
194 break;
195 }
196 spectrumPhy.SetPreambleDetectionModel ("ns3::ThresholdPreambleDetectionModel",
197 "MinimumRssi", DoubleValue (minimumRssi));
198
200 wifi.SetStandard (WIFI_STANDARD_80211ax);
201 if (enableObssPd)
202 {
203 wifi.SetObssPdAlgorithm ("ns3::ConstantObssPdAlgorithm",
204 "ObssPdLevel", DoubleValue (obssPdThreshold));
205 }
206
208 std::ostringstream oss;
209 oss << "HeMcs" << mcs;
210 wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
211 "DataMode", StringValue (oss.str ()),
212 "ControlMode", StringValue (oss.str ()));
213
214 spectrumPhy.Set ("TxPowerStart", DoubleValue (powSta1));
215 spectrumPhy.Set ("TxPowerEnd", DoubleValue (powSta1));
216 spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrSta1));
217 spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
218
219 Ssid ssidA = Ssid ("A");
220 mac.SetType ("ns3::StaWifiMac",
221 "Ssid", SsidValue (ssidA));
222 NetDeviceContainer staDeviceA = wifi.Install (spectrumPhy, mac, wifiStaNodes.Get (0));
223
224 spectrumPhy.Set ("TxPowerStart", DoubleValue (powAp1));
225 spectrumPhy.Set ("TxPowerEnd", DoubleValue (powAp1));
226 spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrAp1));
227 spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
228
229 mac.SetType ("ns3::ApWifiMac",
230 "Ssid", SsidValue (ssidA));
231 NetDeviceContainer apDeviceA = wifi.Install (spectrumPhy, mac, wifiApNodes.Get (0));
232
233 Ptr<WifiNetDevice> apDevice = apDeviceA.Get (0)->GetObject<WifiNetDevice> ();
234 Ptr<ApWifiMac> apWifiMac = apDevice->GetMac ()->GetObject<ApWifiMac> ();
235 if (enableObssPd)
236 {
237 apDevice->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (1));
238 }
239
240 spectrumPhy.Set ("TxPowerStart", DoubleValue (powSta2));
241 spectrumPhy.Set ("TxPowerEnd", DoubleValue (powSta2));
242 spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrSta2));
243 spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
244
245 Ssid ssidB = Ssid ("B");
246 mac.SetType ("ns3::StaWifiMac",
247 "Ssid", SsidValue (ssidB));
248 NetDeviceContainer staDeviceB = wifi.Install (spectrumPhy, mac, wifiStaNodes.Get (1));
249
250 spectrumPhy.Set ("TxPowerStart", DoubleValue (powAp2));
251 spectrumPhy.Set ("TxPowerEnd", DoubleValue (powAp2));
252 spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrAp2));
253 spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
254
255 mac.SetType ("ns3::ApWifiMac",
256 "Ssid", SsidValue (ssidB));
257 NetDeviceContainer apDeviceB = wifi.Install (spectrumPhy, mac, wifiApNodes.Get (1));
258
259 Ptr<WifiNetDevice> ap2Device = apDeviceB.Get (0)->GetObject<WifiNetDevice> ();
260 apWifiMac = ap2Device->GetMac ()->GetObject<ApWifiMac> ();
261 if (enableObssPd)
262 {
263 ap2Device->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (2));
264 }
265
267 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
268 positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // AP1
269 positionAlloc->Add (Vector (d3, 0.0, 0.0)); // AP2
270 positionAlloc->Add (Vector (0.0, d1, 0.0)); // STA1
271 positionAlloc->Add (Vector (d3, d2, 0.0)); // STA2
272 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
273 mobility.SetPositionAllocator (positionAlloc);
274 mobility.Install (wifiApNodes);
275 mobility.Install (wifiStaNodes);
276
277 PacketSocketHelper packetSocket;
278 packetSocket.Install (wifiApNodes);
279 packetSocket.Install (wifiStaNodes);
281 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
282
283 //BSS 1
284 {
285 PacketSocketAddress socketAddr;
286 socketAddr.SetSingleDevice (staDeviceA.Get (0)->GetIfIndex ());
287 socketAddr.SetPhysicalAddress (apDeviceA.Get (0)->GetAddress ());
288 socketAddr.SetProtocol (1);
289 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
290 client->SetRemote (socketAddr);
291 wifiStaNodes.Get (0)->AddApplication (client);
292 client->SetAttribute ("PacketSize", UintegerValue (payloadSize));
293 client->SetAttribute ("MaxPackets", UintegerValue (0));
294 client->SetAttribute ("Interval", TimeValue (Seconds (interval)));
295 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
296 server->SetLocal (socketAddr);
297 wifiApNodes.Get (0)->AddApplication (server);
298 }
299
300 // BSS 2
301 {
302 PacketSocketAddress socketAddr;
303 socketAddr.SetSingleDevice (staDeviceB.Get (0)->GetIfIndex ());
304 socketAddr.SetPhysicalAddress (apDeviceB.Get (0)->GetAddress ());
305 socketAddr.SetProtocol (1);
306 Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
307 client->SetRemote (socketAddr);
308 wifiStaNodes.Get (1)->AddApplication (client);
309 client->SetAttribute ("PacketSize", UintegerValue (payloadSize));
310 client->SetAttribute ("MaxPackets", UintegerValue (0));
311 client->SetAttribute ("Interval", TimeValue (Seconds (interval)));
312 Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
313 server->SetLocal (socketAddr);
314 wifiApNodes.Get (1)->AddApplication (server);
315 }
316
317 Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSocketServer/Rx", MakeCallback (&SocketRx));
318
319 Simulator::Stop (Seconds (duration));
320 Simulator::Run ();
321
322 Simulator::Destroy ();
323
324 for (uint32_t i = 0; i < 2; i++)
325 {
326 double throughput = static_cast<double> (bytesReceived[2 + i]) * 8 / 1000 / 1000 / duration;
327 std::cout << "Throughput for BSS " << i + 1 << ": " << throughput << " Mbit/s" << std::endl;
328 }
329
330 return 0;
331}
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.
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.
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
Hold an unsigned integer type.
Definition: uinteger.h:44
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
helps to create WifiNetDevice objects
Definition: wifi-helper.h:323
create MAC layers for a ns3::WifiNetDevice.
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac(void) const
Ptr< HeConfiguration > GetHeConfiguration(void) const
void SetErrorRateModel(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Definition: wifi-helper.cc:147
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:141
void SetPreambleDetectionModel(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Definition: wifi-helper.cc:193
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
@ WIFI_STANDARD_80211ax
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:96
wifi
Definition: third.py:99
mobility
Definition: third.py:107
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)