diff --git a/CHANGES.html b/CHANGES.html
index 877858e17..705b94d05 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -62,9 +62,10 @@ us a note on ns-developers mailing list.
New attributes QosTxop::AddBaResponseTimeout and QosTxop::FailedAddBaTimeout have been added to set the timeout to wait for an ADDBA response after the ACK to the ADDBA request is received and to set the timeout after a failed BA agreement, respectively.
A new attribute QosTxop::UseExpliciteBarAfterMissedBlockAck has been added to specify whether explicit Block Ack Request should be sent upon missed Block Ack Response.
Added a new trace source EndOfHePreamble in WifiPhy for tracing end of preamble (after training fields) for received 802.11ax packets.
-
Added a new helper method to SpectrumWifiPhyHelper and YansWifiPhyHelper to set the frame capture model
-
Added a new helper method to SpectrumWifiPhyHelper and YansWifiPhyHelper to set the preamble detection model
-
Added a method to ObjectFactory to check whether a TypeId has been configured on the factory
+
Added a new helper method to SpectrumWifiPhyHelper and YansWifiPhyHelper to set the frame capture model.
+
Added a new helper method to SpectrumWifiPhyHelper and YansWifiPhyHelper to set the preamble detection model.
+
Added a method to ObjectFactory to check whether a TypeId has been configured on the factory.
+
Added a new helper method to WifiHelper to set the 802.11ax OBSS PD spatial reuse algorithm.
Changes to existing API:
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 1e5fb1d74..fdbb4b3fa 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -23,7 +23,8 @@ requirements (Note: not all features available on all platforms):
New user-visible features
-------------------------
-- (wifi) Preamble detection can now be modelled
+- (wifi) Preamble detection can now be modelled.
+- (wifi) 802.11ax spatial reuse is now supported.
Bugs fixed
----------
diff --git a/examples/wireless/80211n-mimo.cc b/examples/wireless/80211n-mimo.cc
index 697d9a6b2..4807c786e 100644
--- a/examples/wireless/80211n-mimo.cc
+++ b/examples/wireless/80211n-mimo.cc
@@ -13,7 +13,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Authors: Sébastien Deronne
+ * Author: Sébastien Deronne
*/
// This example is used to validate 802.11n MIMO.
diff --git a/examples/wireless/power-adaptation-distance.cc b/examples/wireless/power-adaptation-distance.cc
index ca059268b..daf2de32c 100644
--- a/examples/wireless/power-adaptation-distance.cc
+++ b/examples/wireless/power-adaptation-distance.cc
@@ -117,7 +117,7 @@ class NodeStatistics
public:
NodeStatistics (NetDeviceContainer aps, NetDeviceContainer stas);
- void PhyCallback (std::string path, Ptr packet);
+ void PhyCallback (std::string path, Ptr packet, double powerW);
void RxCallback (std::string path, Ptr packet, const Address &from);
void PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest);
void RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest);
@@ -203,7 +203,7 @@ NodeStatistics::GetCalcTxTime (DataRate rate)
}
void
-NodeStatistics::PhyCallback (std::string path, Ptr packet)
+NodeStatistics::PhyCallback (std::string path, Ptr packet, double powerW)
{
WifiMacHeader head;
packet->PeekHeader (head);
diff --git a/examples/wireless/power-adaptation-interference.cc b/examples/wireless/power-adaptation-interference.cc
index 9510ac5ae..9725a82d2 100644
--- a/examples/wireless/power-adaptation-interference.cc
+++ b/examples/wireless/power-adaptation-interference.cc
@@ -90,7 +90,7 @@ public:
void CheckStatistics (double time);
- void PhyCallback (std::string path, Ptr packet);
+ void PhyCallback (std::string path, Ptr packet, double powerW);
void RxCallback (std::string path, Ptr packet, const Address &from);
void PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest);
void RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest);
@@ -202,7 +202,7 @@ NodeStatistics::GetCalcTxTime (DataRate rate)
}
void
-NodeStatistics::PhyCallback (std::string path, Ptr packet)
+NodeStatistics::PhyCallback (std::string path, Ptr packet, double powerW)
{
WifiMacHeader head;
packet->PeekHeader (head);
diff --git a/examples/wireless/wifi-pcf.cc b/examples/wireless/wifi-pcf.cc
index ad03ea172..433426c7a 100644
--- a/examples/wireless/wifi-pcf.cc
+++ b/examples/wireless/wifi-pcf.cc
@@ -72,7 +72,7 @@ uint64_t m_countCfEndAck;
uint64_t m_countDataNull;
uint64_t m_countData;
-void TxCallback (std::string context, Ptr p)
+void TxCallback (std::string context, Ptr p, double txPowerW)
{
WifiMacHeader hdr;
p->PeekHeader (hdr);
diff --git a/examples/wireless/wifi-spatial-reuse.cc b/examples/wireless/wifi-spatial-reuse.cc
new file mode 100644
index 000000000..cc1a8050b
--- /dev/null
+++ b/examples/wireless/wifi-spatial-reuse.cc
@@ -0,0 +1,287 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2019 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sébastien Deronne
+ */
+
+//
+// This example program can be used to experiment with spatial
+// reuse mechanisms of 802.11ax.
+//
+// The geometry is as follows:
+//
+// STA1 STA1
+// | |
+// d1 | |d2
+// | d3 |
+// AP1 -----------AP2
+//
+// STA1 and AP1 are in one BSS (with color set to 1), while STA2 and AP2 are in
+// another BSS (with color set to 2). The distances are configurable (d1 through d3).
+//
+// STA1 is continously transmitting data to AP1, while STA2 is continuously sending data to AP2.
+// Each STA has configurable traffic loads (inter packet interval and packet size).
+// It is also possible to configure TX power per node as well as their CCA-ED tresholds.
+// OBSS_PD spatial reuse feature can be enabled (default) or disabled, and the OBSS_PD
+// threshold can be set as well (default: -72 dBm).
+// A simple Friis path loss model is used and a constant PHY rate is considered.
+//
+// In general, the program can be configured at run-time by passing command-line arguments.
+// The following command will display all of the available run-time help options:
+// ./waf --run "wifi-spatial-reuse --help"
+//
+// By default, the script shows the benefit of the OBSS_PD spatial reuse script:
+// ./waf --run wifi-spatial-reuse
+// Throughput for BSS 1: 6.6468 Mbit/s
+// Throughput for BSS 2: 6.6672 Mbit/s
+//
+// If one disables the OBSS_PD feature, a lower throughput is obtained per BSS:
+// ./waf --run "wifi-spatial-reuse --enableObssPd=0"
+// Throughput for BSS 1: 5.8692 Mbit/s
+// Throughput for BSS 2: 5.9364 Mbit/
+//
+// This difference between those results is because OBSS_PD spatial
+// enables to ignore transmissions from another BSS when the received power
+// is below the configured threshold, and therefore either defer during ongoing
+// transmission or transmit at the same time.
+//
+
+#include "ns3/command-line.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/spectrum-wifi-helper.h"
+#include "ns3/ssid.h"
+#include "ns3/mobility-helper.h"
+#include "ns3/application-container.h"
+#include "ns3/multi-model-spectrum-channel.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/ap-wifi-mac.h"
+#include "ns3/he-configuration.h"
+#include "ns3/packet-socket-helper.h"
+#include "ns3/packet-socket-client.h"
+#include "ns3/packet-socket-server.h"
+
+using namespace ns3;
+
+std::vector bytesReceived (4);
+
+uint32_t
+ContextToNodeId (std::string context)
+{
+ std::string sub = context.substr (10);
+ uint32_t pos = sub.find ("/Device");
+ return atoi (sub.substr (0, pos).c_str ());
+}
+
+void
+SocketRx (std::string context, Ptr p, const Address &addr)
+{
+ uint32_t nodeId = ContextToNodeId (context);
+ bytesReceived[nodeId] += p->GetSize ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ double duration = 10.0; // seconds
+ double d1 = 30.0; // meters
+ double d2 = 30.0; // meters
+ double d3 = 150.0; // meters
+ double powSta1 = 10.0; // dBm
+ double powSta2 = 10.0; // dBm
+ double powAp1 = 21.0; // dBm
+ double powAp2 = 21.0; // dBm
+ double ccaEdTrSta1 = -62; // dBm
+ double ccaEdTrSta2 = -62; // dBm
+ double ccaEdTrAp1 = -62; // dBm
+ double ccaEdTrAp2 = -62; // dBm
+ uint32_t payloadSize = 1500; // bytes
+ uint32_t mcs = 0; // MCS value
+ double interval = 0.001; // seconds
+ bool enableObssPd = true;
+ double obssPdThreshold = -72.0; // dBm
+
+ CommandLine cmd;
+ cmd.AddValue ("duration", "Duration of simulation (s)", duration);
+ cmd.AddValue ("interval", "Inter packet interval (s)", interval);
+ cmd.AddValue ("enableObssPd", "Enable/disable OBSS_PD", enableObssPd);
+ cmd.AddValue ("d1", "Distance between STA1 and AP1 (m)", d1);
+ cmd.AddValue ("d2", "Distance between STA2 and AP2 (m)", d2);
+ cmd.AddValue ("d3", "Distance between AP1 and AP2 (m)", d3);
+ cmd.AddValue ("powSta1", "Power of STA1 (dBm)", powSta1);
+ cmd.AddValue ("powSta2", "Power of STA2 (dBm)", powSta2);
+ cmd.AddValue ("powAp1", "Power of AP1 (dBm)", powAp1);
+ cmd.AddValue ("powAp2", "Power of AP2 (dBm)", powAp2);
+ cmd.AddValue ("ccaEdTrSta1", "CCA-ED Threshold of STA1 (dBm)", ccaEdTrSta1);
+ cmd.AddValue ("ccaEdTrSta2", "CCA-ED Threshold of STA2 (dBm)", ccaEdTrSta2);
+ cmd.AddValue ("ccaEdTrAp1", "CCA-ED Threshold of AP1 (dBm)", ccaEdTrAp1);
+ cmd.AddValue ("ccaEdTrAp2", "CCA-ED Threshold of AP2 (dBm)", ccaEdTrAp2);
+ cmd.AddValue ("mcs", "The constant MCS value to transmit HE PPDUs", mcs);
+ cmd.Parse (argc, argv);
+
+ NodeContainer wifiStaNodes;
+ wifiStaNodes.Create (2);
+
+ NodeContainer wifiApNodes;
+ wifiApNodes.Create (2);
+
+ SpectrumWifiPhyHelper spectrumPhy = SpectrumWifiPhyHelper::Default ();
+ Ptr spectrumChannel = CreateObject ();
+ Ptr lossModel = CreateObject ();
+ spectrumChannel->AddPropagationLossModel (lossModel);
+ Ptr delayModel = CreateObject ();
+ spectrumChannel->SetPropagationDelayModel (delayModel);
+
+ spectrumPhy.SetChannel (spectrumChannel);
+ spectrumPhy.SetErrorRateModel ("ns3::YansErrorRateModel");
+ spectrumPhy.Set ("Frequency", UintegerValue (5180)); // channel 36 at 20 MHz
+ spectrumPhy.SetPreambleDetectionModel ("ns3::ThresholdPreambleDetectionModel");
+ //TODO: add parameter to configure CCA-PD
+
+ WifiHelper wifi;
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211ax_5GHZ);
+ if (enableObssPd)
+ {
+ wifi.SetObssPdAlgorithm ("ns3::ConstantObssPdAlgorithm",
+ "ObssPdLevel", DoubleValue (obssPdThreshold));
+ }
+
+ WifiMacHelper mac;
+ std::ostringstream oss;
+ oss << "HeMcs" << mcs;
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
+ "DataMode", StringValue (oss.str ()),
+ "ControlMode", StringValue (oss.str ()));
+
+ spectrumPhy.Set ("TxPowerStart", DoubleValue (powSta1));
+ spectrumPhy.Set ("TxPowerEnd", DoubleValue (powSta1));
+ spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrSta1));
+ spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
+
+ Ssid ssidA = Ssid ("A");
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssidA));
+ NetDeviceContainer staDeviceA = wifi.Install (spectrumPhy, mac, wifiStaNodes.Get (0));
+
+ spectrumPhy.Set ("TxPowerStart", DoubleValue (powAp1));
+ spectrumPhy.Set ("TxPowerEnd", DoubleValue (powAp1));
+ spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrAp1));
+ spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
+
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssidA));
+ NetDeviceContainer apDeviceA = wifi.Install (spectrumPhy, mac, wifiApNodes.Get (0));
+
+ Ptr apDevice = apDeviceA.Get (0)->GetObject ();
+ Ptr apWifiMac = apDevice->GetMac ()->GetObject ();
+ if (enableObssPd)
+ {
+ apDevice->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (1));
+ }
+
+ spectrumPhy.Set ("TxPowerStart", DoubleValue (powSta2));
+ spectrumPhy.Set ("TxPowerEnd", DoubleValue (powSta2));
+ spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrSta2));
+ spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
+
+ Ssid ssidB = Ssid ("B");
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssidB));
+ NetDeviceContainer staDeviceB = wifi.Install (spectrumPhy, mac, wifiStaNodes.Get (1));
+
+ spectrumPhy.Set ("TxPowerStart", DoubleValue (powAp2));
+ spectrumPhy.Set ("TxPowerEnd", DoubleValue (powAp2));
+ spectrumPhy.Set ("CcaEdThreshold", DoubleValue (ccaEdTrAp2));
+ spectrumPhy.Set ("RxSensitivity", DoubleValue (-92.0));
+
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssidB));
+ NetDeviceContainer apDeviceB = wifi.Install (spectrumPhy, mac, wifiApNodes.Get (1));
+
+ Ptr ap2Device = apDeviceB.Get (0)->GetObject ();
+ apWifiMac = ap2Device->GetMac ()->GetObject ();
+ if (enableObssPd)
+ {
+ ap2Device->GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (2));
+ }
+
+ MobilityHelper mobility;
+ Ptr positionAlloc = CreateObject ();
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // AP1
+ positionAlloc->Add (Vector (d3, 0.0, 0.0)); // AP2
+ positionAlloc->Add (Vector (0.0, d1, 0.0)); // STA1
+ positionAlloc->Add (Vector (d3, d2, 0.0)); // STA2
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.Install (wifiApNodes);
+ mobility.Install (wifiStaNodes);
+
+ PacketSocketHelper packetSocket;
+ packetSocket.Install (wifiApNodes);
+ packetSocket.Install (wifiStaNodes);
+ ApplicationContainer apps;
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+
+ //BSS 1
+ {
+ PacketSocketAddress socketAddr;
+ socketAddr.SetSingleDevice (staDeviceA.Get (0)->GetIfIndex ());
+ socketAddr.SetPhysicalAddress (apDeviceA.Get (0)->GetAddress ());
+ socketAddr.SetProtocol (1);
+ Ptr client = CreateObject ();
+ client->SetRemote (socketAddr);
+ wifiStaNodes.Get (0)->AddApplication (client);
+ client->SetAttribute ("PacketSize", UintegerValue (payloadSize));
+ client->SetAttribute ("MaxPackets", UintegerValue (0));
+ client->SetAttribute ("Interval", TimeValue (Seconds (interval)));
+ Ptr server = CreateObject ();
+ server->SetLocal (socketAddr);
+ wifiApNodes.Get (0)->AddApplication (server);
+ }
+
+ // BSS 2
+ {
+ PacketSocketAddress socketAddr;
+ socketAddr.SetSingleDevice (staDeviceB.Get (0)->GetIfIndex ());
+ socketAddr.SetPhysicalAddress (apDeviceB.Get (0)->GetAddress ());
+ socketAddr.SetProtocol (1);
+ Ptr client = CreateObject ();
+ client->SetRemote (socketAddr);
+ wifiStaNodes.Get (1)->AddApplication (client);
+ client->SetAttribute ("PacketSize", UintegerValue (payloadSize));
+ client->SetAttribute ("MaxPackets", UintegerValue (0));
+ client->SetAttribute ("Interval", TimeValue (Seconds (interval)));
+ Ptr server = CreateObject ();
+ server->SetLocal (socketAddr);
+ wifiApNodes.Get (1)->AddApplication (server);
+ }
+
+ Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSocketServer/Rx", MakeCallback (&SocketRx));
+
+ Simulator::Stop (Seconds (duration));
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+
+ for (uint32_t i = 0; i < 2; i++)
+ {
+ double throughput = static_cast (bytesReceived[2 + i]) * 8 / 1000 / 1000 / duration;
+ std::cout << "Throughput for BSS " << i + 1 << ": " << throughput << " Mbit/s" << std::endl;
+ }
+
+ return 0;
+}
diff --git a/examples/wireless/wscript b/examples/wireless/wscript
index 839c545f4..3396e9fb3 100644
--- a/examples/wireless/wscript
+++ b/examples/wireless/wscript
@@ -115,3 +115,6 @@ def build(bld):
obj = bld.create_ns3_program('wifi-pcf', ['wifi', 'applications'])
obj.source = 'wifi-pcf.cc'
+
+ obj = bld.create_ns3_program('wifi-spatial-reuse', ['wifi', 'applications'])
+ obj.source = 'wifi-spatial-reuse.cc'
diff --git a/src/netanim/model/animation-interface.cc b/src/netanim/model/animation-interface.cc
index b7372fc39..cb30fd99c 100644
--- a/src/netanim/model/animation-interface.cc
+++ b/src/netanim/model/animation-interface.cc
@@ -867,7 +867,7 @@ AnimationInterface::UanPhyGenRxTrace (std::string context, Ptr p)
}
void
-AnimationInterface::WifiPhyTxBeginTrace (std::string context, Ptr p)
+AnimationInterface::WifiPhyTxBeginTrace (std::string context, Ptr p, double txPowerW)
{
NS_LOG_FUNCTION (this);
return GenericWirelessTxTrace (context, p, AnimationInterface::WIFI);
diff --git a/src/netanim/model/animation-interface.h b/src/netanim/model/animation-interface.h
index 28794a58f..29f073a10 100644
--- a/src/netanim/model/animation-interface.h
+++ b/src/netanim/model/animation-interface.h
@@ -1047,8 +1047,9 @@ private:
* wifi Phy transmit begin trace function
* \param context the context
* \param p the packet
+ * \param txPowerW the tx power
*/
- void WifiPhyTxBeginTrace (std::string context, Ptr p);
+ void WifiPhyTxBeginTrace (std::string context, Ptr p, double txPowerW);
/**
* wifi Phy receive begin trace function
*
diff --git a/src/wifi/doc/source/wifi-design.rst b/src/wifi/doc/source/wifi-design.rst
index 2d3f46709..576ac42f8 100644
--- a/src/wifi/doc/source/wifi-design.rst
+++ b/src/wifi/doc/source/wifi-design.rst
@@ -20,7 +20,7 @@ on the IEEE 802.11 standard [ieee80211]_. We will go into more detail below but
|ns3| provides models for these aspects of 802.11:
* basic 802.11 DCF with **infrastructure** and **adhoc** modes
-* **802.11a**, **802.11b**, **802.11g**, **802.11n** (both 2.4 and 5 GHz bands), **802.11ac** and **802.11ax** Draft 1.0 (both 2.4 and 5 GHz bands) physical layers
+* **802.11a**, **802.11b**, **802.11g**, **802.11n** (both 2.4 and 5 GHz bands), **802.11ac** and **802.11ax** (both 2.4 and 5 GHz bands) physical layers
* **MSDU aggregation** and **MPDU aggregation** extensions of 802.11n, and both can be combined together (two-level aggregation)
* QoS-based EDCA and queueing extensions of **802.11e**
* the ability to use different propagation loss models and propagation delay models,
@@ -164,10 +164,7 @@ combines the effect of thermal noise and of interference from other Wi-Fi
packets. Moreover, interference from other technologies is not modeled.
The following details pertain to the physical layer and channel models:
-* 802.11ax is still in draft phase, not all functionalities are implemented yet
-* 802.11ax does not contain any of the high-density improvement
* 802.11ax MU-OFDMA is not supported
-* 802.11ax can only be used with Constant rate control algorithm
* 802.11ax only supports SU PPDU format
* 802.11ac/ax MU-MIMO is not supported, and no more than 4 antennas can be configured
* 802.11n/ac/ax beamforming is not supported
@@ -704,6 +701,40 @@ The goal of the lookaround rate is to force minstrel to try higher rate than the
For a more detailed information about minstrel, see [linuxminstrel]_.
+802.11ax OBSS PD spatial reuse
+##############################
+
+802.11ax mode supports OBSS PD spatial reuse feature.
+OBSS PD stands for Overlapping Basic Service Set Preamble-Detection.
+OBSS PD is an 802.11ax specific feature that allows a STA, under specific conditions,
+to ignore an inter-BSS PPDU.
+
+OBSS PD Algorithm
+#################
+
+``ObssPdAlgorithm`` is the base class of OBSS PD algorithms.
+It implements the common functionalities. First, it makes sure the necessary callbacks are setup.
+Second, when a PHY reset is requested by the algorithm, it performs the computation to determine the TX power
+restrictions and informs the PHY object.
+
+The PHY keeps tracks of incoming requests from the MAC to get access to the channel.
+If a request is received and if PHY reset(s) indicating TX power limitations occured
+before a packet was transmitted, the next packet to be transmitted will be sent with
+a reduced power. Otherwise, no TX power restrictions will be applied.
+
+Constant OBSS PD Algorithm
+##########################
+
+Constant OBSS PD algorithm is a simple OBSS PD algorithm implemmented in the ``ConstantObssPdAlgorithm`` class.
+
+Once a HE preamble and its header have been received by the PHY, ``ConstantObssPdAlgorithm::
+ReceiveHeSig`` is triggered.
+The algorithm then checks whether this is an OBSS frame by comparing its own BSS color with the BSS color of the received preamble.
+If this is an OBSS frame, it compare the received RSSI with its configured OBSS PD level value. The PHY then gets reset to IDLE
+state in case the received RSSI is lower than that constant OBSS PD level value, and is informed about a TX power restrictions.
+
+Note: since our model is based on a single threshold, the PHY only supports one restricted power level.
+
Modifying Wifi model
####################
diff --git a/src/wifi/doc/source/wifi-user.rst b/src/wifi/doc/source/wifi-user.rst
index 6c0bd5de1..5ba2b9fd6 100644
--- a/src/wifi/doc/source/wifi-user.rst
+++ b/src/wifi/doc/source/wifi-user.rst
@@ -736,7 +736,15 @@ In order to change parameters that are overwritten by ``WifiHelper::SetStandard`
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BasicBlockAckTimeout", TimeValue (MicroSeconds (basicBlockAckTimeout)));
Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/CompressedBlockAckTimeout", TimeValue (MicroSeconds (compressedBlockAckTimeout)));
-There are many |ns3| attributes that can be set on the above helpers to
+The WifiHelper is also used to configure OBSS PD spatial reuse for 802.11ax.
+The following line configure a WifiHelper to support OBSS PD spatial reuse
+using the ``ConstantObssPdAlgorithm`` with a threshold set to -72 dBm::
+
+ WifiHelper wifi;
+ wifi.SetObssPdAlgorithm ("ns3::ConstantObssPdAlgorithm",
+ "ObssPdLevel", DoubleValue (-72.0));
+
+There are many other |ns3| attributes that can be set on the above helpers to
deviate from the default behavior; the example scripts show how to do some of
this reconfiguration.
diff --git a/src/wifi/helper/wifi-helper.cc b/src/wifi/helper/wifi-helper.cc
index 8de1142cf..1b293a2b8 100644
--- a/src/wifi/helper/wifi-helper.cc
+++ b/src/wifi/helper/wifi-helper.cc
@@ -37,6 +37,7 @@
#include "ns3/ht-configuration.h"
#include "ns3/vht-configuration.h"
#include "ns3/he-configuration.h"
+#include "ns3/obss-pd-algorithm.h"
#include "wifi-helper.h"
namespace ns3 {
@@ -672,6 +673,29 @@ WifiHelper::SetRemoteStationManager (std::string type,
m_stationManager.Set (n7, v7);
}
+void
+WifiHelper::SetObssPdAlgorithm (std::string type,
+ std::string n0, const AttributeValue &v0,
+ std::string n1, const AttributeValue &v1,
+ std::string n2, const AttributeValue &v2,
+ std::string n3, const AttributeValue &v3,
+ std::string n4, const AttributeValue &v4,
+ std::string n5, const AttributeValue &v5,
+ std::string n6, const AttributeValue &v6,
+ std::string n7, const AttributeValue &v7)
+{
+ m_obssPdAlgorithm = ObjectFactory ();
+ m_obssPdAlgorithm.SetTypeId (type);
+ m_obssPdAlgorithm.Set (n0, v0);
+ m_obssPdAlgorithm.Set (n1, v1);
+ m_obssPdAlgorithm.Set (n2, v2);
+ m_obssPdAlgorithm.Set (n3, v3);
+ m_obssPdAlgorithm.Set (n4, v4);
+ m_obssPdAlgorithm.Set (n5, v5);
+ m_obssPdAlgorithm.Set (n6, v6);
+ m_obssPdAlgorithm.Set (n7, v7);
+}
+
void
WifiHelper::SetStandard (WifiPhyStandard standard)
{
@@ -720,6 +744,13 @@ WifiHelper::Install (const WifiPhyHelper &phyHelper,
device->SetPhy (phy);
device->SetRemoteStationManager (manager);
node->AddDevice (device);
+ if ((m_standard >= WIFI_PHY_STANDARD_80211ax_2_4GHZ) && (m_obssPdAlgorithm.IsTypeIdSet ()))
+
+ {
+ Ptr obssPdAlgorithm = m_obssPdAlgorithm.Create ();
+ device->AggregateObject (obssPdAlgorithm);
+ obssPdAlgorithm->ConnectWifiNetDevice (device);
+ }
devices.Add (device);
NS_LOG_DEBUG ("node=" << node << ", mob=" << node->GetObject ());
// Aggregate a NetDeviceQueueInterface object if a RegularWifiMac is installed
@@ -807,6 +838,7 @@ WifiHelper::EnableLogComponents (void)
LogComponentEnable ("BlockAckCache", LOG_LEVEL_ALL);
LogComponentEnable ("BlockAckManager", LOG_LEVEL_ALL);
LogComponentEnable ("CaraWifiManager", LOG_LEVEL_ALL);
+ LogComponentEnable ("ConstantObssPdAlgorithm", LOG_LEVEL_ALL);
LogComponentEnable ("ConstantRateWifiManager", LOG_LEVEL_ALL);
LogComponentEnable ("Txop", LOG_LEVEL_ALL);
LogComponentEnable ("ChannelAccessManager", LOG_LEVEL_ALL);
@@ -823,6 +855,7 @@ WifiHelper::EnableLogComponents (void)
LogComponentEnable ("MpduAggregator", LOG_LEVEL_ALL);
LogComponentEnable ("MsduAggregator", LOG_LEVEL_ALL);
LogComponentEnable ("NistErrorRateModel", LOG_LEVEL_ALL);
+ LogComponentEnable ("ObssPdAlgorithm", LOG_LEVEL_ALL);
LogComponentEnable ("OnoeWifiManager", LOG_LEVEL_ALL);
LogComponentEnable ("ParfWifiManager", LOG_LEVEL_ALL);
LogComponentEnable ("RegularWifiMac", LOG_LEVEL_ALL);
diff --git a/src/wifi/helper/wifi-helper.h b/src/wifi/helper/wifi-helper.h
index 742e33d71..b849565e3 100644
--- a/src/wifi/helper/wifi-helper.h
+++ b/src/wifi/helper/wifi-helper.h
@@ -338,6 +338,38 @@ public:
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+ /**
+ * \param type the type of ns3::ObssPdAlgorithm to create.
+ * \param n0 the name of the attribute to set
+ * \param v0 the value of the attribute to set
+ * \param n1 the name of the attribute to set
+ * \param v1 the value of the attribute to set
+ * \param n2 the name of the attribute to set
+ * \param v2 the value of the attribute to set
+ * \param n3 the name of the attribute to set
+ * \param v3 the value of the attribute to set
+ * \param n4 the name of the attribute to set
+ * \param v4 the value of the attribute to set
+ * \param n5 the name of the attribute to set
+ * \param v5 the value of the attribute to set
+ * \param n6 the name of the attribute to set
+ * \param v6 the value of the attribute to set
+ * \param n7 the name of the attribute to set
+ * \param v7 the value of the attribute to set
+ *
+ * All the attributes specified in this method should exist
+ * in the requested algorithm.
+ */
+ void SetObssPdAlgorithm (std::string type,
+ 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 ());
+
/// Callback invoked to determine the MAC queue selected for a given packet
typedef std::function)> SelectQueueCallback;
@@ -436,6 +468,7 @@ protected:
ObjectFactory m_stationManager; ///< station manager
WifiPhyStandard m_standard; ///< wifi standard
SelectQueueCallback m_selectQueueCallback; ///< select queue callback
+ ObjectFactory m_obssPdAlgorithm; ///< OBSS PD algorithm
};
} //namespace ns3
diff --git a/src/wifi/model/channel-access-manager.cc b/src/wifi/model/channel-access-manager.cc
index deaf07beb..af9b4d2e0 100644
--- a/src/wifi/model/channel-access-manager.cc
+++ b/src/wifi/model/channel-access-manager.cc
@@ -139,6 +139,7 @@ ChannelAccessManager::DoDispose (void)
i->Dispose ();
i = 0;
}
+ m_phy = 0;
}
void
@@ -148,6 +149,7 @@ ChannelAccessManager::SetupPhyListener (Ptr phy)
NS_ASSERT (m_phyListener == 0);
m_phyListener = new PhyListener (this);
phy->RegisterListener (m_phyListener);
+ m_phy = phy;
}
void
@@ -259,6 +261,10 @@ void
ChannelAccessManager::RequestAccess (Ptr state, bool isCfPeriod)
{
NS_LOG_FUNCTION (this << state);
+ if (m_phy)
+ {
+ m_phy->NotifyChannelAccessRequested ();
+ }
//Deny access if in sleep mode or off
if (m_sleeping || m_off)
{
diff --git a/src/wifi/model/channel-access-manager.h b/src/wifi/model/channel-access-manager.h
index f309a5e44..23219d44c 100644
--- a/src/wifi/model/channel-access-manager.h
+++ b/src/wifi/model/channel-access-manager.h
@@ -319,6 +319,7 @@ private:
Time m_slot; //!< the slot time
Time m_sifs; //!< the SIFS time
PhyListener* m_phyListener; //!< the phy listener
+ Ptr m_phy; //!< Ptr to the PHY
};
} //namespace ns3
diff --git a/src/wifi/model/constant-obss-pd-algorithm.cc b/src/wifi/model/constant-obss-pd-algorithm.cc
new file mode 100644
index 000000000..10e68458a
--- /dev/null
+++ b/src/wifi/model/constant-obss-pd-algorithm.cc
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2018 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sébastien Deronne
+ */
+
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/config.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+#include "constant-obss-pd-algorithm.h"
+#include "sta-wifi-mac.h"
+#include "wifi-utils.h"
+#include "wifi-phy.h"
+#include "wifi-net-device.h"
+#include "he-configuration.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("ConstantObssPdAlgorithm");
+NS_OBJECT_ENSURE_REGISTERED (ConstantObssPdAlgorithm);
+
+ConstantObssPdAlgorithm::ConstantObssPdAlgorithm ()
+ : ObssPdAlgorithm ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+TypeId
+ConstantObssPdAlgorithm::GetTypeId (void)
+{
+ static ns3::TypeId tid = ns3::TypeId ("ns3::ConstantObssPdAlgorithm")
+ .SetParent ()
+ .SetGroupName ("Wifi")
+ .AddConstructor ()
+ ;
+ return tid;
+}
+
+void
+ConstantObssPdAlgorithm::ConnectWifiNetDevice (const Ptr device)
+{
+ Ptr phy = device->GetPhy ();
+ phy->TraceConnectWithoutContext ("EndOfHePreamble", MakeCallback (&ConstantObssPdAlgorithm::ReceiveHeSig, this));
+ ObssPdAlgorithm::ConnectWifiNetDevice (device);
+}
+
+void
+ConstantObssPdAlgorithm::ReceiveHeSig (HePreambleParameters params)
+{
+ NS_LOG_FUNCTION (this << +params.bssColor << WToDbm (params.rssiW));
+
+ Ptr mac = m_device->GetMac ()->GetObject();
+ if (mac && !mac->IsAssociated ())
+ {
+ NS_LOG_DEBUG ("This is not an associated STA: skip OBSS PD algorithm");
+ return;
+ }
+
+ Ptr heConfiguration = m_device->GetHeConfiguration ();
+ NS_ASSERT (heConfiguration);
+ UintegerValue bssColorAttribute;
+ heConfiguration->GetAttribute ("BssColor", bssColorAttribute);
+ uint8_t bssColor = bssColorAttribute.Get ();
+
+ if (bssColor == 0)
+ {
+ NS_LOG_DEBUG ("BSS color is 0");
+ return;
+ }
+ if (params.bssColor == 0)
+ {
+ NS_LOG_DEBUG ("Received BSS color is 0");
+ return;
+ }
+ //TODO: SRP_AND_NON-SRG_OBSS-PD_PROHIBITED=1 => OBSS_PD SR is not allowed
+
+ bool isObss = (bssColor != params.bssColor);
+ if (isObss)
+ {
+ if (WToDbm (params.rssiW) < m_obssPdLevel)
+ {
+ NS_LOG_DEBUG ("Frame is OBSS and RSSI " << WToDbm(params.rssiW) << " is below OBSS-PD level of " << m_obssPdLevel << "; reset PHY to IDLE");
+ ResetPhy (params);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("Frame is OBSS and RSSI is above OBSS-PD level");
+ }
+ }
+}
+
+} //namespace ns3
diff --git a/src/wifi/model/constant-obss-pd-algorithm.h b/src/wifi/model/constant-obss-pd-algorithm.h
new file mode 100644
index 000000000..dd4759d52
--- /dev/null
+++ b/src/wifi/model/constant-obss-pd-algorithm.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2018 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sébastien Deronne
+ */
+
+#ifndef CONSTANT_OBSS_PD_ALGORITHM_H
+#define CONSTANT_OBSS_PD_ALGORITHM_H
+
+#include "obss-pd-algorithm.h"
+
+namespace ns3 {
+
+/**
+ * \brief Constant OBSS PD algorithm
+ * \ingroup wifi
+ *
+ * This constant OBSS_PD algorithm is a simple OBSS_PD algorithm which evalutes if a receiving
+ * signal should be accepted or rejected based on a constant threshold.
+ *
+ * Once a HE preamble and its header have been received by the PHY, the ReceiveHeSig method is
+ * triggered. The algorithm then checks whether this is an OBSS frame by comparing its own BSS
+ * color with the BSS color of the received preamble. If this is an OBSS frame, it compares the
+ * received RSSI with its configured OBSS_PD level value. The PHY then gets reset to IDLE state
+ * in case the received RSSI is lower than that constant OBSS PD level value, and is informed
+ * about TX power restrictions that might be applied to the next tranmission.
+ */
+class ConstantObssPdAlgorithm : public ObssPdAlgorithm
+{
+public:
+ ConstantObssPdAlgorithm ();
+
+ static TypeId GetTypeId (void);
+
+ /**
+ * Connect the WifiNetDevice and setup eventual callbacks.
+ *
+ * \param device the WifiNetDevice
+ */
+ void ConnectWifiNetDevice (const Ptr device);
+
+ /**
+ * \param params the HE SIG parameters
+ *
+ * Evaluate the receipt of HE SIG.
+ */
+ void ReceiveHeSig (HePreambleParameters params);
+};
+
+} //namespace ns3
+
+#endif /* CONSTANT_OBSS_PD_ALGORITHM_H */
diff --git a/src/wifi/model/he-configuration.h b/src/wifi/model/he-configuration.h
index 0e5f6d3e2..64d930f3e 100644
--- a/src/wifi/model/he-configuration.h
+++ b/src/wifi/model/he-configuration.h
@@ -21,6 +21,7 @@
#define HE_CONFIGURATION_H
#include "ns3/object.h"
+#include "ns3/nstime.h"
namespace ns3 {
diff --git a/src/wifi/model/obss-pd-algorithm.cc b/src/wifi/model/obss-pd-algorithm.cc
new file mode 100644
index 000000000..0661dba77
--- /dev/null
+++ b/src/wifi/model/obss-pd-algorithm.cc
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2018 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sébastien Deronne
+ */
+
+#include "ns3/log.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+#include "obss-pd-algorithm.h"
+#include "wifi-net-device.h"
+#include "wifi-phy.h"
+#include "wifi-utils.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("ObssPdAlgorithm");
+NS_OBJECT_ENSURE_REGISTERED (ObssPdAlgorithm);
+
+TypeId
+ObssPdAlgorithm::GetTypeId (void)
+{
+ static ns3::TypeId tid = ns3::TypeId ("ns3::ObssPdAlgorithm")
+ .SetParent