From 4f349d7f4752ed47ac1698183d356d45252aface Mon Sep 17 00:00:00 2001
From: Tom Henderson
Date: Fri, 22 Jul 2016 18:13:42 -0700
Subject: [PATCH] wifi: (closes #2400) Add SpectrumWifiPhy model
---
CHANGES.html | 13 +-
RELEASE_NOTES | 5 +
examples/wireless/examples-to-run.py | 4 +
.../wireless/wifi-spectrum-per-example.cc | 565 ++++++
.../wifi-spectrum-per-interference.cc | 627 +++++++
.../wifi-spectrum-saturation-example.cc | 701 +++++++
examples/wireless/wscript | 8 +
.../model/wifi-spectrum-value-helper.cc | 343 +++-
.../model/wifi-spectrum-value-helper.h | 151 +-
src/wifi/doc/source/wifi-design.rst | 122 +-
src/wifi/doc/source/wifi-testing.rst | 161 +-
src/wifi/doc/source/wifi-user.rst | 11 +-
src/wifi/helper/spectrum-wifi-helper.cc | 687 +++++++
src/wifi/helper/spectrum-wifi-helper.h | 187 ++
src/wifi/model/interference-helper.cc | 8 +
src/wifi/model/interference-helper.h | 6 +
src/wifi/model/spectrum-wifi-phy.cc | 1663 +++++++++++++++++
src/wifi/model/spectrum-wifi-phy.h | 685 +++++++
src/wifi/model/wifi-mode.h | 1 +
src/wifi/model/wifi-phy-tag.cc | 107 ++
src/wifi/model/wifi-phy-tag.h | 83 +
src/wifi/model/wifi-phy.cc | 2 +-
src/wifi/model/wifi-spectrum-phy-interface.cc | 117 ++
src/wifi/model/wifi-spectrum-phy-interface.h | 72 +
.../model/wifi-spectrum-signal-parameters.cc | 58 +
.../model/wifi-spectrum-signal-parameters.h | 60 +
src/wifi/test/spectrum-wifi-phy-test.cc | 261 +++
src/wifi/wscript | 13 +-
28 files changed, 6650 insertions(+), 71 deletions(-)
create mode 100644 examples/wireless/wifi-spectrum-per-example.cc
create mode 100644 examples/wireless/wifi-spectrum-per-interference.cc
create mode 100644 examples/wireless/wifi-spectrum-saturation-example.cc
create mode 100644 src/wifi/helper/spectrum-wifi-helper.cc
create mode 100644 src/wifi/helper/spectrum-wifi-helper.h
create mode 100644 src/wifi/model/spectrum-wifi-phy.cc
create mode 100644 src/wifi/model/spectrum-wifi-phy.h
create mode 100644 src/wifi/model/wifi-phy-tag.cc
create mode 100644 src/wifi/model/wifi-phy-tag.h
create mode 100644 src/wifi/model/wifi-spectrum-phy-interface.cc
create mode 100644 src/wifi/model/wifi-spectrum-phy-interface.h
create mode 100644 src/wifi/model/wifi-spectrum-signal-parameters.cc
create mode 100644 src/wifi/model/wifi-spectrum-signal-parameters.h
create mode 100644 src/wifi/test/spectrum-wifi-phy-test.cc
diff --git a/CHANGES.html b/CHANGES.html
index 5aa1cc848..e8cce28db 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -54,14 +54,14 @@ us a note on ns-developers mailing list.
Changes from ns-3.25 to ns-3.26
New API:
-- A SocketPriorityTag is introduced to carry the packet priority. Such a tag
+
- A SocketPriorityTag is introduced to carry the packet priority. Such a tag
is added to packets by sockets that support this mechanism (UdpSocketImpl,
TcpSocketBase and PacketSocket). The base class Socket has a new SetPriority
method to set the socket priority. When the IPv4 protocol is used, the
priority is set based on the ToS. See the Socket options section of the
Network model for more information.
-- A WifiNetDevice::SelectQueue method has been added to determine the user
+
- A WifiNetDevice::SelectQueue method has been added to determine the user
priority of an MSDU. This method is called by the traffic control layer before
enqueuing a packet in the queue disc, if a queue disc is installed on
the outgoing device, or passing a packet to the device, otherwise. The
@@ -69,11 +69,12 @@ us a note on ns-developers mailing list.
(TOS field in case of IPv4 and Traffic Class field in case of IPv6). The
packet priority carried by the SocketPriorityTag is set to the user priority.
-- The PfifoFastQueueDisc classifies packets into bands based on their priority.
+
- The PfifoFastQueueDisc classifies packets into bands based on their priority.
See the pfifo_fast queue disc section of the Traffic Control Layer model
for more information.
-- The attributes YansWifiPhy::Frequency, YansWifiPhy::ChannelNumber, and YansWifiPhy::ChannelWidth, and the related accessor methods, were moved to base class WifiPhy. YansWifiPhy::GetChannelFrequencyMhz() was deleted. A new method WifiPhy::DefineChannelNumber () was added to allow users to define relationships between channel number, standard, frequency, and channel width.
+
- A new class SpectrumWifiPhy has been introduced that makes use of the Spectrum module. Its functionality and API is currently very similar to that of the YansWifiPhy, especially because it reuses the same InterferenceHelper and ErrorModel classes (for this release). Some example programs in the 'examples/wireless/' directory, such as 'wifi-spectrum-per-example.cc', illustrate how the SpectrumWifiPhy class can be substituted for the default YansWifiPhy PHY model.
+
Changes to existing API:
@@ -94,6 +95,10 @@ us a note on ns-developers mailing list.
- The QosTag is removed as it has been superseded by the SocketPriorityTag.
- The Ipv4L3Protocol::DefaultTos attribute is removed.
+- The attributes YansWifiPhy::Frequency, YansWifiPhy::ChannelNumber, and YansWifiPhy::ChannelWidth, and the related accessor methods, were moved to base class WifiPhy. YansWifiPhy::GetChannelFrequencyMhz() was deleted. A new method WifiPhy::DefineChannelNumber () was added to allow users to define relationships between channel number, standard, frequency, and channel width.
+
+- The class WifiSpectrumValueHelper has been refactored; previously it was an abstract base class supporting the WifiSpectrumValue5MhzFactory spectrum model. It now contains various static member methods supporting the creation of power spectral densities with the granularity of a Wi-Fi OFDM subcarrier bandwidth. The class WifiSpectrumValue5MhzFactory and its API remain but it is not subclassed.
+- A new method InterferenceHelper::AddForeignSignal has been introduced to support use of the SpectrumWifiPhy (so that non-Wi-Fi signals may be handled as noise power).
Changes to build system:
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 22e2f0f15..5dfddd0d9 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -36,6 +36,11 @@ New user-visible features
- (internet) Added TCP YeAH congestion control algorithm
- (network) SocketAddressTag has been removed from the codebase.
Users can use RecvFrom (for UDP) or GetPeerName (for TCP) instead.
+- (wifi) A new SpectrumWifiPhy physical layer model, making use of the
+ ns-3 spectrum framework, has been introduced. The current version of
+ this model matches the API and behavior of YansWifiPhy closely, but
+ over time is expected to support a different PHY abstraction and error
+ models.
Bugs fixed
----------
diff --git a/examples/wireless/examples-to-run.py b/examples/wireless/examples-to-run.py
index 859d5567b..e1c1df786 100755
--- a/examples/wireless/examples-to-run.py
+++ b/examples/wireless/examples-to-run.py
@@ -32,6 +32,10 @@ cpp_examples = [
("ofdm-vht-validation", "True", "True"),
("mixed-bg-network", "True", "True"),
("wifi-tcp", "True", "True"),
+ ("wifi-spectrum-per-example --distance=52 --index=3 --wifiType=ns3::SpectrumWifiPhy --simulationTime=1", "True", "True"),
+ ("wifi-spectrum-per-example --distance=24 --index=31 --wifiType=ns3::YansWifiPhy --simulationTime=1", "True", "True"),
+ ("wifi-spectrum-per-interference --distance=24 --index=31 --simulationTime=1 --waveformPower=0.1", "True", "True"),
+ ("wifi-spectrum-saturation-example --simulationTime=1 --index=63", "True", "True"),
]
# A list of Python examples to run in order to ensure that they remain
diff --git a/examples/wireless/wifi-spectrum-per-example.cc b/examples/wireless/wifi-spectrum-per-example.cc
new file mode 100644
index 000000000..cbbf0b9ea
--- /dev/null
+++ b/examples/wireless/wifi-spectrum-per-example.cc
@@ -0,0 +1,565 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ * Copyright (c) 2015 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
+ *
+ * Authors: Mirko Banchi
+ * Sebastien Deronne
+ * Tom Henderson
+ *
+ * Adapted from ht-wifi-network.cc example
+ */
+#include
+#include
+
+#include "ns3/core-module.h"
+#include "ns3/config-store-module.h"
+#include "ns3/network-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/spectrum-module.h"
+#include "ns3/internet-module.h"
+
+// This is a simple example of an IEEE 802.11n Wi-Fi network.
+//
+// The main use case is to enable and test SpectrumWifiPhy vs YansWifiPhy
+// for packet error ratio
+//
+// Network topology:
+//
+// Wi-Fi 192.168.1.0
+//
+// STA AP
+// * <-- distance --> *
+// | |
+// n1 n2
+//
+// Users may vary the following command-line arguments in addition to the
+// attributes, global values, and default values typically available:
+//
+// --simulationTime: Simulation time in seconds [10]
+// --udp: UDP if set to 1, TCP otherwise [true]
+// --distance: meters separation between nodes [50]
+// --index: restrict index to single value between 0 and 31 [256]
+// --wifiType: select ns3::SpectrumWifiPhy or ns3::YansWifiPhy [ns3::SpectrumWifiPhy]
+// --errorModelType: select ns3::NistErrorRateModel or ns3::YansErrorRateModel [ns3::NistErrorRateModel]
+// --enablePcap: enable pcap output [false]
+//
+// By default, the program will step through 32 index values, corresponding
+// to the following MCS, channel width, and guard interval combinations:
+// index 0-7: MCS 0-7, long guard interval, 20 MHz channel
+// index 8-15: MCS 0-7, short guard interval, 20 MHz channel
+// index 16-23: MCS 0-7, long guard interval, 40 MHz channel
+// index 24-31: MCS 0-7, short guard interval, 40 MHz channel
+// and send 1000 UDP packets using each MCS, using the SpectrumWifiPhy and the
+// NistErrorRateModel, at a distance of 50 meters. The program outputs
+// results such as:
+//
+// wifiType: ns3::SpectrumWifiPhy distance: 50m; sent: 1000
+// index MCS Rate (Mb/s) Tput (Mb/s) Received Signal (dBm) Noise (dBm) SNR (dB)
+// 0 0 6.5 0.7776 1000 -77.6633 -100.966 23.3027
+// 1 1 13 0.7776 1000 -77.6633 -100.966 23.3027
+// 2 2 19.5 0.7776 1000 -77.6633 -100.966 23.3027
+// 3 3 26 0.7776 1000 -77.6633 -100.966 23.3027
+// ...
+//
+// When UDP is used, the throughput will always be 0.7776 Mb/s since the
+// traffic generator does not attempt to match the maximum Phy data rate
+// but instead sends at a constant rate. When TCP is used, the TCP flow
+// will exhibit different throughput depending on the index.
+
+using namespace ns3;
+
+// Global variables for use in callbacks.
+double g_signalDbmAvg;
+double g_noiseDbmAvg;
+uint32_t g_samples;
+uint16_t g_channelNumber;
+uint32_t g_rate;
+
+void MonitorSniffRx (Ptr packet, uint16_t channelFreqMhz,
+ uint16_t channelNumber, uint32_t rate,
+ WifiPreamble preamble, WifiTxVector txVector,
+ struct mpduInfo aMpdu, struct signalNoiseDbm signalNoise)
+
+{
+ g_samples++;
+ g_signalDbmAvg += ((signalNoise.signal - g_signalDbmAvg) / g_samples);
+ g_noiseDbmAvg += ((signalNoise.noise - g_noiseDbmAvg) / g_samples);
+ g_rate = rate;
+ g_channelNumber = channelNumber;
+}
+
+NS_LOG_COMPONENT_DEFINE ("WifiSpectrumPerExample");
+
+int main (int argc, char *argv[])
+{
+ bool udp = true;
+ double distance = 50;
+ double simulationTime = 10; //seconds
+ uint16_t index = 256;
+ std::string wifiType = "ns3::SpectrumWifiPhy";
+ std::string errorModelType = "ns3::NistErrorRateModel";
+ bool enablePcap = false;
+ const uint32_t tcpPacketSize = 1448;
+
+ CommandLine cmd;
+ cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
+ cmd.AddValue ("udp", "UDP if set to 1, TCP otherwise", udp);
+ cmd.AddValue ("distance", "meters separation between nodes", distance);
+ cmd.AddValue ("index", "restrict index to single value between 0 and 31", index);
+ cmd.AddValue ("wifiType", "select ns3::SpectrumWifiPhy or ns3::YansWifiPhy", wifiType);
+ cmd.AddValue ("errorModelType", "select ns3::NistErrorRateModel or ns3::YansErrorRateModel", errorModelType);
+ cmd.AddValue ("enablePcap", "enable pcap output", enablePcap);
+ cmd.Parse (argc,argv);
+
+ uint16_t startIndex = 0;
+ uint16_t stopIndex = 31;
+ if (index < 32)
+ {
+ startIndex = index;
+ stopIndex = index;
+ }
+
+ std::cout << "wifiType: " << wifiType << " distance: " << distance << "m; sent: 1000 TxPower: 1 dBm (1.3 mW)" << std::endl;
+ std::cout << std::setw (5) << "index" <<
+ std::setw (6) << "MCS" <<
+ std::setw (12) << "Rate (Mb/s)" <<
+ std::setw (12) << "Tput (Mb/s)" <<
+ std::setw (10) << "Received " <<
+ std::setw (12) << "Signal (dBm)" <<
+ std::setw (12) << "Noise (dBm)" <<
+ std::setw (10) << "SNR (dB)" <<
+ std::endl;
+ for (uint16_t i = startIndex; i <= stopIndex; i++)
+ {
+ uint32_t payloadSize;
+ if (udp)
+ {
+ payloadSize = 972; // 1000 bytes IPv4
+ }
+ else
+ {
+ payloadSize = 1448; // 1500 bytes IPv6
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
+ }
+
+ NodeContainer wifiStaNode;
+ wifiStaNode.Create (1);
+ NodeContainer wifiApNode;
+ wifiApNode.Create (1);
+
+ YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+ SpectrumWifiPhyHelper spectrumPhy = SpectrumWifiPhyHelper::Default ();
+ if (wifiType == "ns3::YansWifiPhy")
+ {
+ YansWifiChannelHelper channel;
+ channel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
+ channel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ phy.SetChannel (channel.Create ());
+ phy.Set ("TxPowerStart", DoubleValue (1)); // dBm (1.26 mW)
+ phy.Set ("TxPowerEnd", DoubleValue (1));
+
+ if (i <= 7)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ phy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 7 && i <= 15)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ phy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 15 && i <= 23)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ phy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ else
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ phy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ }
+ else if (wifiType == "ns3::SpectrumWifiPhy")
+ {
+ Ptr spectrumChannel
+ = CreateObject ();
+ Ptr lossModel
+ = CreateObject ();
+ spectrumChannel->AddPropagationLossModel (lossModel);
+
+ Ptr delayModel
+ = CreateObject ();
+ spectrumChannel->SetPropagationDelayModel (delayModel);
+
+ spectrumPhy.SetChannel (spectrumChannel);
+ spectrumPhy.SetErrorRateModel (errorModelType);
+ spectrumPhy.Set ("Frequency", UintegerValue (5180));
+ spectrumPhy.Set ("TxPowerStart", DoubleValue (1)); // dBm (1.26 mW)
+ spectrumPhy.Set ("TxPowerEnd", DoubleValue (1));
+
+ if (i <= 7)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 7 && i <= 15)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 15 && i <= 23)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ else
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Unsupported WiFi type " << wifiType);
+ }
+
+
+ WifiHelper wifi;
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
+ WifiMacHelper mac;
+
+ Ssid ssid = Ssid ("ns380211n");
+
+ double datarate = 0;
+ StringValue DataRate;
+ if (i == 0)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 6.5;
+ }
+ else if (i == 1)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 13;
+ }
+ else if (i == 2)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 19.5;
+ }
+ else if (i == 3)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 26;
+ }
+ else if (i == 4)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 39;
+ }
+ else if (i == 5)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 52;
+ }
+ else if (i == 6)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 58.5;
+ }
+ else if (i == 7)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 65;
+ }
+ else if (i == 8)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 7.2;
+ }
+ else if (i == 9)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 14.4;
+ }
+ else if (i == 10)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 21.7;
+ }
+ else if (i == 11)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 28.9;
+ }
+ else if (i == 12)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 43.3;
+ }
+ else if (i == 13)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 57.8;
+ }
+ else if (i == 14)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 65;
+ }
+ else if (i == 15)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 72.2;
+ }
+ else if (i == 16)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 13.5;
+ }
+ else if (i == 17)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 27;
+ }
+ else if (i == 18)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 40.5;
+ }
+ else if (i == 19)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 54;
+ }
+ else if (i == 20)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 81;
+ }
+ else if (i == 21)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 108;
+ }
+ else if (i == 22)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 121.5;
+ }
+ else if (i == 23)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 135;
+ }
+ else if (i == 24)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 15;
+ }
+ else if (i == 25)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 30;
+ }
+ else if (i == 26)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 45;
+ }
+ else if (i == 27)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 60;
+ }
+ else if (i == 28)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 90;
+ }
+ else if (i == 29)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 120;
+ }
+ else if (i == 30)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 135;
+ }
+ else
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 150;
+ }
+
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
+ "ControlMode", DataRate);
+
+ NetDeviceContainer staDevice;
+ NetDeviceContainer apDevice;
+
+ if (wifiType == "ns3::YansWifiPhy")
+ {
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+ staDevice = wifi.Install (phy, mac, wifiStaNode);
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+ apDevice = wifi.Install (phy, mac, wifiApNode);
+
+ }
+ else if (wifiType == "ns3::SpectrumWifiPhy")
+ {
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+ staDevice = wifi.Install (spectrumPhy, mac, wifiStaNode);
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+ apDevice = wifi.Install (spectrumPhy, mac, wifiApNode);
+ }
+
+ // mobility.
+ MobilityHelper mobility;
+ Ptr positionAlloc = CreateObject ();
+
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (distance, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+ mobility.Install (wifiApNode);
+ mobility.Install (wifiStaNode);
+
+ /* Internet stack*/
+ InternetStackHelper stack;
+ stack.Install (wifiApNode);
+ stack.Install (wifiStaNode);
+
+ Ipv4AddressHelper address;
+
+ address.SetBase ("192.168.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer staNodeInterface;
+ Ipv4InterfaceContainer apNodeInterface;
+
+ staNodeInterface = address.Assign (staDevice);
+ apNodeInterface = address.Assign (apDevice);
+
+ /* Setting applications */
+ ApplicationContainer serverApp, sinkApp;
+ if (udp)
+ {
+ //UDP flow
+ UdpServerHelper myServer (9);
+ serverApp = myServer.Install (wifiStaNode.Get (0));
+ serverApp.Start (Seconds (0.0));
+ serverApp.Stop (Seconds (simulationTime + 1));
+
+ UdpClientHelper myClient (staNodeInterface.GetAddress (0), 9);
+ myClient.SetAttribute ("MaxPackets", UintegerValue (1000));
+ myClient.SetAttribute ("Interval", TimeValue (MilliSeconds (5)));
+ myClient.SetAttribute ("PacketSize", UintegerValue (payloadSize));
+
+ ApplicationContainer clientApp = myClient.Install (wifiApNode.Get (0));
+ clientApp.Start (Seconds (1.0));
+ clientApp.Stop (Seconds (simulationTime + 1));
+ }
+ else
+ {
+ //TCP flow
+ uint16_t port = 50000;
+ Address apLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+ PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", apLocalAddress);
+ sinkApp = packetSinkHelper.Install (wifiStaNode.Get (0));
+
+ sinkApp.Start (Seconds (0.0));
+ sinkApp.Stop (Seconds (simulationTime + 1));
+
+ OnOffHelper onoff ("ns3::TcpSocketFactory",Ipv4Address::GetAny ());
+ onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
+ onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
+ onoff.SetAttribute ("PacketSize", UintegerValue (payloadSize));
+ onoff.SetAttribute ("DataRate", DataRateValue (1000000000)); //bit/s
+ ApplicationContainer apps;
+
+ AddressValue remoteAddress (InetSocketAddress (staNodeInterface.GetAddress (0), port));
+ onoff.SetAttribute ("Remote", remoteAddress);
+ apps.Add (onoff.Install (wifiApNode.Get (0)));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (simulationTime + 1));
+ }
+
+ Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/Phy/MonitorSnifferRx", MakeCallback (&MonitorSniffRx));
+
+ if (enablePcap)
+ {
+ std::stringstream ss;
+ ss << "wifi-spectrum-per-example-" << i;
+ phy.EnablePcap (ss.str (), apDevice);
+ }
+ g_signalDbmAvg = 0;
+ g_noiseDbmAvg = 0;
+ g_samples = 0;
+ g_channelNumber = 0;
+ g_rate = 0;
+
+ Simulator::Stop (Seconds (simulationTime + 1));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ double throughput = 0;
+ uint32_t totalPacketsThrough = 0;
+ if (udp)
+ {
+ //UDP
+ totalPacketsThrough = DynamicCast (serverApp.Get (0))->GetReceived ();
+ throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ else
+ {
+ //TCP
+ uint32_t totalBytesRx = DynamicCast (sinkApp.Get (0))->GetTotalRx ();
+ totalPacketsThrough = totalBytesRx / tcpPacketSize;
+ throughput = totalBytesRx * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ std::cout << std::setw (5) << i <<
+ std::setw (6) << (i % 8) <<
+ std::setw (10) << datarate <<
+ std::setw (12) << throughput <<
+ std::setw (8) << totalPacketsThrough;
+ if (totalPacketsThrough > 0)
+ {
+ std::cout << std::setw (12) << g_signalDbmAvg <<
+ std::setw (12) << g_noiseDbmAvg <<
+ std::setw (12) << (g_signalDbmAvg - g_noiseDbmAvg) <<
+ std::endl;
+ }
+ else
+ {
+ std::cout << std::setw (12) << "N/A" <<
+ std::setw (12) << "N/A" <<
+ std::setw (12) << "N/A" <<
+ std::endl;
+ }
+ }
+ return 0;
+}
diff --git a/examples/wireless/wifi-spectrum-per-interference.cc b/examples/wireless/wifi-spectrum-per-interference.cc
new file mode 100644
index 000000000..103460d2d
--- /dev/null
+++ b/examples/wireless/wifi-spectrum-per-interference.cc
@@ -0,0 +1,627 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ * Copyright (c) 2015 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
+ *
+ * Authors: Mirko Banchi
+ * Sebastien Deronne
+ * Tom Henderson
+ *
+ * Adapted from ht-wifi-network.cc example
+ */
+#include
+#include
+
+#include "ns3/core-module.h"
+#include "ns3/config-store-module.h"
+#include "ns3/network-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/spectrum-module.h"
+#include "ns3/internet-module.h"
+
+// This is a simple example of an IEEE 802.11n Wi-Fi network with a
+// non-Wi-Fi interferer. It is an adaptation of the wifi-spectrum-per-example
+//
+// Unless the --waveformPower argument is passed, it will behave like
+// wifi-spectrum-per-example. Adding --waveformPower=value for values
+// greater than 0.0001 will result in frame losses beyond those that
+// result from the normal SNR based on distance path loss.
+//
+// If YansWifiPhy is selected as the wifiType, --waveformPower will have
+// no effect.
+//
+// Network topology:
+//
+// Wi-Fi 192.168.1.0
+//
+// STA AP
+// * <-- distance --> *
+// | |
+// n1 n2
+//
+// Users may vary the following command-line arguments in addition to the
+// attributes, global values, and default values typically available:
+//
+// --simulationTime: Simulation time in seconds [10]
+// --udp: UDP if set to 1, TCP otherwise [true]
+// --distance: meters separation between nodes [50]
+// --index: restrict index to single value between 0 and 31 [256]
+// --wifiType: select ns3::SpectrumWifiPhy or ns3::YansWifiPhy [ns3::SpectrumWifiPhy]
+// --errorModelType: select ns3::NistErrorRateModel or ns3::YansErrorRateModel [ns3::NistErrorRateModel]
+// --enablePcap: enable pcap output [false]
+// --waveformPower: Waveform power [0]
+//
+// By default, the program will step through 32 index values, corresponding
+// to the following MCS, channel width, and guard interval combinations:
+// index 0-7: MCS 0-7, long guard interval, 20 MHz channel
+// index 8-15: MCS 0-7, short guard interval, 20 MHz channel
+// index 16-23: MCS 0-7, long guard interval, 40 MHz channel
+// index 24-31: MCS 0-7, short guard interval, 40 MHz channel
+// and send 1000 UDP packets using each MCS, using the SpectrumWifiPhy and the
+// NistErrorRateModel, at a distance of 50 meters. The program outputs
+// results such as:
+//
+// wifiType: ns3::SpectrumWifiPhy distance: 50m; sent: 1000
+// index MCS Rate (Mb/s) Tput (Mb/s) Received Signal (dBm) Noise (dBm) SNR (dB)
+// 0 0 6.5 0.7776 1000 -77.6633 -100.966 23.3027
+// 1 1 13 0.7776 1000 -77.6633 -100.966 23.3027
+// 2 2 19.5 0.7776 1000 -77.6633 -100.966 23.3027
+// 3 3 26 0.7776 1000 -77.6633 -100.966 23.3027
+// ...
+//
+// When UDP is used, the throughput will always be 0.7776 Mb/s since the
+// traffic generator does not attempt to match the maximum Phy data rate
+// but instead sends at a constant rate. When TCP is used, the TCP flow
+// will exhibit different throughput depending on the index.
+
+using namespace ns3;
+
+// Global variables for use in callbacks.
+double g_signalDbmAvg;
+double g_noiseDbmAvg;
+uint32_t g_samples;
+uint16_t g_channelNumber;
+uint32_t g_rate;
+
+void MonitorSniffRx (Ptr packet, uint16_t channelFreqMhz,
+ uint16_t channelNumber, uint32_t rate,
+ WifiPreamble preamble, WifiTxVector txVector,
+ struct mpduInfo aMpdu, struct signalNoiseDbm signalNoise)
+
+{
+ g_samples++;
+ g_signalDbmAvg += ((signalNoise.signal - g_signalDbmAvg) / g_samples);
+ g_noiseDbmAvg += ((signalNoise.noise - g_noiseDbmAvg) / g_samples);
+ g_rate = rate;
+ g_channelNumber = channelNumber;
+}
+
+NS_LOG_COMPONENT_DEFINE ("WifiSpectrumPerInterference");
+
+Ptr SpectrumModelWifi5180MHz;
+
+class static_SpectrumModelWifi5180MHz_initializer
+{
+public:
+ static_SpectrumModelWifi5180MHz_initializer ()
+ {
+ BandInfo bandInfo;
+ bandInfo.fc = 5180e6;
+ bandInfo.fl = 5180e6 - 10e6;
+ bandInfo.fh = 5180e6 + 10e6;
+
+ Bands bands;
+ bands.push_back (bandInfo);
+
+ SpectrumModelWifi5180MHz = Create (bands);
+ }
+
+} static_SpectrumModelWifi5180MHz_initializer_instance;
+
+int main (int argc, char *argv[])
+{
+ bool udp = true;
+ double distance = 50;
+ double simulationTime = 10; //seconds
+ uint16_t index = 256;
+ std::string wifiType = "ns3::SpectrumWifiPhy";
+ std::string errorModelType = "ns3::NistErrorRateModel";
+ bool enablePcap = false;
+ const uint32_t tcpPacketSize = 1448;
+ double waveformPower = 0;
+
+ CommandLine cmd;
+ cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
+ cmd.AddValue ("udp", "UDP if set to 1, TCP otherwise", udp);
+ cmd.AddValue ("distance", "meters separation between nodes", distance);
+ cmd.AddValue ("index", "restrict index to single value between 0 and 31", index);
+ cmd.AddValue ("wifiType", "select ns3::SpectrumWifiPhy or ns3::YansWifiPhy", wifiType);
+ cmd.AddValue ("errorModelType", "select ns3::NistErrorRateModel or ns3::YansErrorRateModel", errorModelType);
+ cmd.AddValue ("enablePcap", "enable pcap output", enablePcap);
+ cmd.AddValue ("waveformPower", "Waveform power", waveformPower);
+ cmd.Parse (argc,argv);
+
+ uint16_t startIndex = 0;
+ uint16_t stopIndex = 31;
+ if (index < 32)
+ {
+ startIndex = index;
+ stopIndex = index;
+ }
+
+ std::cout << "wifiType: " << wifiType << " distance: " << distance << "m; sent: 1000 TxPower: 16 dBm (40 mW)" << std::endl;
+ std::cout << std::setw (5) << "index" <<
+ std::setw (6) << "MCS" <<
+ std::setw (12) << "Rate (Mb/s)" <<
+ std::setw (12) << "Tput (Mb/s)" <<
+ std::setw (10) << "Received " <<
+ std::setw (12) << "Signal (dBm)" <<
+ std::setw (12) << "Noi+Inf(dBm)" <<
+ std::setw (10) << "SNR (dB)" <<
+ std::endl;
+ for (uint16_t i = startIndex; i <= stopIndex; i++)
+ {
+ uint32_t payloadSize;
+ if (udp)
+ {
+ payloadSize = 972; // 1000 bytes IPv4
+ }
+ else
+ {
+ payloadSize = 1448; // 1500 bytes IPv6
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
+ }
+
+ NodeContainer wifiStaNode;
+ wifiStaNode.Create (1);
+ NodeContainer wifiApNode;
+ wifiApNode.Create (1);
+ NodeContainer interferingNode;
+ interferingNode.Create (1);
+
+ YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+ SpectrumWifiPhyHelper spectrumPhy = SpectrumWifiPhyHelper::Default ();
+ Ptr spectrumChannel;
+ if (wifiType == "ns3::YansWifiPhy")
+ {
+ YansWifiChannelHelper channel;
+ channel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
+ channel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ phy.SetChannel (channel.Create ());
+ phy.Set ("Frequency", UintegerValue (5180));
+
+ if (i <= 7)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ phy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 7 && i <= 15)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ phy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 15 && i <= 23)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ phy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ else
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ phy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ }
+ else if (wifiType == "ns3::SpectrumWifiPhy")
+ {
+ spectrumChannel
+ = CreateObject ();
+ Ptr lossModel
+ = CreateObject ();
+ spectrumChannel->AddPropagationLossModel (lossModel);
+
+
+ Ptr delayModel
+ = CreateObject ();
+ spectrumChannel->SetPropagationDelayModel (delayModel);
+
+ spectrumPhy.SetChannel (spectrumChannel);
+ spectrumPhy.SetErrorRateModel (errorModelType);
+ spectrumPhy.Set ("Frequency", UintegerValue (5180)); // channel 36 at 20 MHz
+
+ if (i <= 7)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 7 && i <= 15)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (20));
+ }
+ else if (i > 15 && i <= 23)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ else
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ spectrumPhy.Set ("ChannelWidth", UintegerValue (40));
+ }
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Unsupported WiFi type " << wifiType);
+ }
+
+
+ WifiHelper wifi;
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
+ WifiMacHelper mac;
+
+ Ssid ssid = Ssid ("ns380211n");
+
+ double datarate = 0;
+ StringValue DataRate;
+ if (i == 0)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 6.5;
+ }
+ else if (i == 1)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 13;
+ }
+ else if (i == 2)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 19.5;
+ }
+ else if (i == 3)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 26;
+ }
+ else if (i == 4)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 39;
+ }
+ else if (i == 5)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 52;
+ }
+ else if (i == 6)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 58.5;
+ }
+ else if (i == 7)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 65;
+ }
+ else if (i == 8)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 7.2;
+ }
+ else if (i == 9)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 14.4;
+ }
+ else if (i == 10)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 21.7;
+ }
+ else if (i == 11)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 28.9;
+ }
+ else if (i == 12)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 43.3;
+ }
+ else if (i == 13)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 57.8;
+ }
+ else if (i == 14)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 65;
+ }
+ else if (i == 15)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 72.2;
+ }
+ else if (i == 16)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 13.5;
+ }
+ else if (i == 17)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 27;
+ }
+ else if (i == 18)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 40.5;
+ }
+ else if (i == 19)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 54;
+ }
+ else if (i == 20)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 81;
+ }
+ else if (i == 21)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 108;
+ }
+ else if (i == 22)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 121.5;
+ }
+ else if (i == 23)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 135;
+ }
+ else if (i == 24)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 15;
+ }
+ else if (i == 25)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 30;
+ }
+ else if (i == 26)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 45;
+ }
+ else if (i == 27)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 60;
+ }
+ else if (i == 28)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 90;
+ }
+ else if (i == 29)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 120;
+ }
+ else if (i == 30)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 135;
+ }
+ else
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 150;
+ }
+
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
+ "ControlMode", DataRate);
+
+ NetDeviceContainer staDevice;
+ NetDeviceContainer apDevice;
+
+ if (wifiType == "ns3::YansWifiPhy")
+ {
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+ staDevice = wifi.Install (phy, mac, wifiStaNode);
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+ apDevice = wifi.Install (phy, mac, wifiApNode);
+
+ }
+ else if (wifiType == "ns3::SpectrumWifiPhy")
+ {
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+ staDevice = wifi.Install (spectrumPhy, mac, wifiStaNode);
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+ apDevice = wifi.Install (spectrumPhy, mac, wifiApNode);
+ }
+
+ // mobility.
+ MobilityHelper mobility;
+ Ptr positionAlloc = CreateObject ();
+
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (distance, 0.0, 0.0));
+ positionAlloc->Add (Vector (distance, distance, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+ mobility.Install (wifiApNode);
+ mobility.Install (wifiStaNode);
+ mobility.Install (interferingNode);
+
+ /* Internet stack*/
+ InternetStackHelper stack;
+ stack.Install (wifiApNode);
+ stack.Install (wifiStaNode);
+
+ Ipv4AddressHelper address;
+
+ address.SetBase ("192.168.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer staNodeInterface;
+ Ipv4InterfaceContainer apNodeInterface;
+
+ staNodeInterface = address.Assign (staDevice);
+ apNodeInterface = address.Assign (apDevice);
+
+ /* Setting applications */
+ ApplicationContainer serverApp, sinkApp;
+ if (udp)
+ {
+ //UDP flow
+ UdpServerHelper myServer (9);
+ serverApp = myServer.Install (wifiStaNode.Get (0));
+ serverApp.Start (Seconds (0.0));
+ serverApp.Stop (Seconds (simulationTime + 1));
+
+ UdpClientHelper myClient (staNodeInterface.GetAddress (0), 9);
+ myClient.SetAttribute ("MaxPackets", UintegerValue (1000));
+ myClient.SetAttribute ("Interval", TimeValue (MilliSeconds (5)));
+ myClient.SetAttribute ("PacketSize", UintegerValue (payloadSize));
+
+ ApplicationContainer clientApp = myClient.Install (wifiApNode.Get (0));
+ clientApp.Start (Seconds (1.0));
+ clientApp.Stop (Seconds (simulationTime + 1));
+ }
+ else
+ {
+ //TCP flow
+ uint16_t port = 50000;
+ Address apLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+ PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", apLocalAddress);
+ sinkApp = packetSinkHelper.Install (wifiStaNode.Get (0));
+
+ sinkApp.Start (Seconds (0.0));
+ sinkApp.Stop (Seconds (simulationTime + 1));
+
+ OnOffHelper onoff ("ns3::TcpSocketFactory",Ipv4Address::GetAny ());
+ onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
+ onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
+ onoff.SetAttribute ("PacketSize", UintegerValue (payloadSize));
+ onoff.SetAttribute ("DataRate", DataRateValue (1000000000)); //bit/s
+ ApplicationContainer apps;
+
+ AddressValue remoteAddress (InetSocketAddress (staNodeInterface.GetAddress (0), port));
+ onoff.SetAttribute ("Remote", remoteAddress);
+ apps.Add (onoff.Install (wifiApNode.Get (0)));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (simulationTime + 1));
+ }
+ // Configure waveform generator
+
+ Ptr wgPsd = Create (SpectrumModelWifi5180MHz);
+ *wgPsd = waveformPower / (100 * 180000);
+ NS_LOG_INFO ("wgPsd : " << *wgPsd << " integrated power: " << Integral (*(GetPointer (wgPsd))));
+
+ if (wifiType == "ns3::SpectrumWifiPhy")
+ {
+ WaveformGeneratorHelper waveformGeneratorHelper;
+ waveformGeneratorHelper.SetChannel (spectrumChannel);
+ waveformGeneratorHelper.SetTxPowerSpectralDensity (wgPsd);
+
+ waveformGeneratorHelper.SetPhyAttribute ("Period", TimeValue (Seconds (0.0007)));
+ waveformGeneratorHelper.SetPhyAttribute ("DutyCycle", DoubleValue (1));
+ NetDeviceContainer waveformGeneratorDevices = waveformGeneratorHelper.Install (interferingNode);
+
+ Simulator::Schedule (Seconds (0.002), &WaveformGenerator::Start,
+ waveformGeneratorDevices.Get (0)->GetObject ()->GetPhy ()->GetObject ());
+ }
+
+ Config::ConnectWithoutContext ("/NodeList/0/DeviceList/*/Phy/MonitorSnifferRx", MakeCallback (&MonitorSniffRx));
+
+ if (enablePcap)
+ {
+ std::stringstream ss;
+ ss << "wifi-spectrum-per-example-" << i;
+ phy.EnablePcap (ss.str (), apDevice);
+ }
+ g_signalDbmAvg = 0;
+ g_noiseDbmAvg = 0;
+ g_samples = 0;
+ g_channelNumber = 0;
+ g_rate = 0;
+
+ // Make sure we are tuned to 5180 MHz; if not, the example will
+ // not work properly
+ Ptr staDevicePtr = staDevice.Get (0);
+ Ptr wifiStaDevicePtr = staDevicePtr->GetObject ();
+ UintegerValue val;
+ wifiStaDevicePtr->GetPhy ()->GetAttribute ("Frequency", val);
+ if (val.Get () != 5180)
+ {
+ NS_FATAL_ERROR ("Error: Wi-Fi nodes must be tuned to 5180 MHz to match the waveform generator");
+ }
+
+ Simulator::Stop (Seconds (simulationTime + 1));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ double throughput = 0;
+ uint32_t totalPacketsThrough = 0;
+ if (udp)
+ {
+ //UDP
+ totalPacketsThrough = DynamicCast (serverApp.Get (0))->GetReceived ();
+ throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ else
+ {
+ //TCP
+ uint32_t totalBytesRx = DynamicCast (sinkApp.Get (0))->GetTotalRx ();
+ totalPacketsThrough = totalBytesRx / tcpPacketSize;
+ throughput = totalBytesRx * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ std::cout << std::setw (5) << i <<
+ std::setw (6) << (i % 8) <<
+ std::setw (10) << datarate <<
+ std::setw (12) << throughput <<
+ std::setw (8) << totalPacketsThrough;
+ if (totalPacketsThrough > 0)
+ {
+ std::cout << std::setw (12) << g_signalDbmAvg <<
+ std::setw (12) << g_noiseDbmAvg <<
+ std::setw (12) << (g_signalDbmAvg - g_noiseDbmAvg) <<
+ std::endl;
+ }
+ else
+ {
+ std::cout << std::setw (12) << "N/A" <<
+ std::setw (12) << "N/A" <<
+ std::setw (12) << "N/A" <<
+ std::endl;
+ }
+ }
+ return 0;
+}
diff --git a/examples/wireless/wifi-spectrum-saturation-example.cc b/examples/wireless/wifi-spectrum-saturation-example.cc
new file mode 100644
index 000000000..4dedf2979
--- /dev/null
+++ b/examples/wireless/wifi-spectrum-saturation-example.cc
@@ -0,0 +1,701 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ * Copyright (c) 2015 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
+ *
+ * Authors: Mirko Banchi
+ * Sebastien Deronne
+ * Tom Henderson
+ *
+ * Adapted from ht-wifi-network.cc example
+ */
+#include
+#include
+
+#include "ns3/core-module.h"
+#include "ns3/config-store-module.h"
+#include "ns3/network-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/spectrum-module.h"
+#include "ns3/internet-module.h"
+
+// This is a simple example of an IEEE 802.11n Wi-Fi network.
+//
+// The main use case is to enable and test SpectrumWifiPhy vs YansWifiPhy
+// under saturation conditions (for max throughput).
+//
+// Network topology:
+//
+// Wi-Fi 192.168.1.0
+//
+// STA AP
+// * <-- distance --> *
+// | |
+// n1 n2
+//
+// Users may vary the following command-line arguments in addition to the
+// attributes, global values, and default values typically available:
+//
+// --simulationTime: Simulation time in seconds [10]
+// --distance: meters separation between nodes [50]
+// --index: restrict index to single value between 0 and 31 [256]
+// --wifiType: select ns3::SpectrumWifiPhy or ns3::YansWifiPhy [ns3::SpectrumWifiPhy]
+// --errorModelType: select ns3::NistErrorRateModel or ns3::YansErrorRateModel [ns3::NistErrorRateModel]
+// --enablePcap: enable pcap output [false]
+//
+// By default, the program will step through 64 index values, corresponding
+// to the following MCS, channel width, and guard interval combinations:
+// index 0-7: MCS 0-7, long guard interval, 20 MHz channel
+// index 8-15: MCS 0-7, short guard interval, 20 MHz channel
+// index 16-23: MCS 0-7, long guard interval, 40 MHz channel
+// index 24-31: MCS 0-7, short guard interval, 40 MHz channel
+// index 32-39: MCS 8-15, long guard interval, 20 MHz channel
+// index 40-47: MCS 8-15, short guard interval, 20 MHz channel
+// index 48-55: MCS 8-15, long guard interval, 40 MHz channel
+// index 56-63: MCS 8-15, short guard interval, 40 MHz channel
+// and send packets at a high rate using each MCS, using the SpectrumWifiPhy
+// and the NistErrorRateModel, at a distance of 1 meter. The program outputs
+// results such as:
+//
+// wifiType: ns3::SpectrumWifiPhy distance: 1m
+// index MCS width Rate (Mb/s) Tput (Mb/s) Received
+// 0 0 20 6.5 5.96219 5063
+// 1 1 20 13 11.9491 10147
+// 2 2 20 19.5 17.9184 15216
+// 3 3 20 26 23.9253 20317
+// ...
+//
+// selection of index values 32-63 will result in MCS selection 8-15
+// involving two spatial streams
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("WifiSpectrumSaturationExample");
+
+int main (int argc, char *argv[])
+{
+ double distance = 1;
+ double simulationTime = 10; //seconds
+ uint16_t index = 256;
+ uint32_t channelWidth;
+ std::string wifiType = "ns3::SpectrumWifiPhy";
+ std::string errorModelType = "ns3::NistErrorRateModel";
+ bool enablePcap = false;
+
+ CommandLine cmd;
+ cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
+ cmd.AddValue ("distance", "meters separation between nodes", distance);
+ cmd.AddValue ("index", "restrict index to single value between 0 and 63", index);
+ cmd.AddValue ("wifiType", "select ns3::SpectrumWifiPhy or ns3::YansWifiPhy", wifiType);
+ cmd.AddValue ("errorModelType", "select ns3::NistErrorRateModel or ns3::YansErrorRateModel", errorModelType);
+ cmd.AddValue ("enablePcap", "enable pcap output", enablePcap);
+ cmd.Parse (argc,argv);
+
+ uint16_t startIndex = 0;
+ uint16_t stopIndex = 63;
+ if (index < 64)
+ {
+ startIndex = index;
+ stopIndex = index;
+ }
+
+ std::cout << "wifiType: " << wifiType << " distance: " << distance << "m" << std::endl;
+ std::cout << std::setw (5) << "index" <<
+ std::setw (6) << "MCS" <<
+ std::setw (8) << "width" <<
+ std::setw (12) << "Rate (Mb/s)" <<
+ std::setw (12) << "Tput (Mb/s)" <<
+ std::setw (10) << "Received " <<
+ std::endl;
+ for (uint16_t i = startIndex; i <= stopIndex; i++)
+ {
+ uint32_t payloadSize;
+ payloadSize = 1472; // 1500 bytes IPv4
+
+ NodeContainer wifiStaNode;
+ wifiStaNode.Create (1);
+ NodeContainer wifiApNode;
+ wifiApNode.Create (1);
+
+ YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+ SpectrumWifiPhyHelper spectrumPhy = SpectrumWifiPhyHelper::Default ();
+ if (wifiType == "ns3::YansWifiPhy")
+ {
+ YansWifiChannelHelper channel;
+ channel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
+ channel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ phy.SetChannel (channel.Create ());
+ phy.Set ("TxPowerStart", DoubleValue (1));
+ phy.Set ("TxPowerEnd", DoubleValue (1));
+
+ if (i <= 7)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ channelWidth = 20;
+ }
+ else if (i > 7 && i <= 15)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ channelWidth = 20;
+ }
+ else if (i > 15 && i <= 23)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ channelWidth = 40;
+ }
+ else if (i > 23 && i <= 31)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ channelWidth = 40;
+ }
+ else if (i > 31 && i <= 39)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ phy.Set ("RxAntennas", UintegerValue (2));
+ phy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 20;
+ }
+ else if (i > 39 && i <= 47)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ phy.Set ("RxAntennas", UintegerValue (2));
+ phy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 20;
+ }
+ else if (i > 47 && i <= 55)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (false));
+ phy.Set ("RxAntennas", UintegerValue (2));
+ phy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 40;
+ }
+ else if (i > 55 && i <= 63)
+ {
+ phy.Set ("ShortGuardEnabled", BooleanValue (true));
+ phy.Set ("RxAntennas", UintegerValue (2));
+ phy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 40;
+ }
+ }
+ else if (wifiType == "ns3::SpectrumWifiPhy")
+ {
+ Ptr spectrumChannel
+ = CreateObject ();
+ Ptr lossModel
+ = CreateObject ();
+ spectrumChannel->AddPropagationLossModel (lossModel);
+
+ Ptr delayModel
+ = CreateObject ();
+ spectrumChannel->SetPropagationDelayModel (delayModel);
+
+ spectrumPhy.SetChannel (spectrumChannel);
+ spectrumPhy.SetErrorRateModel (errorModelType);
+ spectrumPhy.Set ("Frequency", UintegerValue (5180)); // channel 36 at 20 MHz
+ spectrumPhy.Set ("TxPowerStart", DoubleValue (1));
+ spectrumPhy.Set ("TxPowerEnd", DoubleValue (1));
+
+ if (i <= 7)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ channelWidth = 20;
+ }
+ else if (i > 7 && i <= 15)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ channelWidth = 20;
+ }
+ else if (i > 15 && i <= 23)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ channelWidth = 40;
+ }
+ else if (i > 23 && i <= 31)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ channelWidth = 40;
+ }
+ else if (i > 31 && i <= 39)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ spectrumPhy.Set ("RxAntennas", UintegerValue (2));
+ spectrumPhy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 20;
+ }
+ else if (i > 39 && i <= 47)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ spectrumPhy.Set ("RxAntennas", UintegerValue (2));
+ spectrumPhy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 20;
+ }
+ else if (i > 47 && i <= 55)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (false));
+ spectrumPhy.Set ("RxAntennas", UintegerValue (2));
+ spectrumPhy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 40;
+ }
+ else if (i > 55 && i <= 63)
+ {
+ spectrumPhy.Set ("ShortGuardEnabled", BooleanValue (true));
+ spectrumPhy.Set ("RxAntennas", UintegerValue (2));
+ spectrumPhy.Set ("TxAntennas", UintegerValue (2));
+ channelWidth = 40;
+ }
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Unsupported WiFi type " << wifiType);
+ }
+
+
+ WifiHelper wifi;
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
+ WifiMacHelper mac;
+
+ Ssid ssid = Ssid ("ns380211n");
+
+ double datarate = 0;
+ StringValue DataRate;
+ if (i == 0)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 6.5;
+ }
+ else if (i == 1)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 13;
+ }
+ else if (i == 2)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 19.5;
+ }
+ else if (i == 3)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 26;
+ }
+ else if (i == 4)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 39;
+ }
+ else if (i == 5)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 52;
+ }
+ else if (i == 6)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 58.5;
+ }
+ else if (i == 7)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 65;
+ }
+ else if (i == 8)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 7.2;
+ }
+ else if (i == 9)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 14.4;
+ }
+ else if (i == 10)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 21.7;
+ }
+ else if (i == 11)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 28.9;
+ }
+ else if (i == 12)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 43.3;
+ }
+ else if (i == 13)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 57.8;
+ }
+ else if (i == 14)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 65;
+ }
+ else if (i == 15)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 72.2;
+ }
+ else if (i == 16)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 13.5;
+ }
+ else if (i == 17)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 27;
+ }
+ else if (i == 18)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 40.5;
+ }
+ else if (i == 19)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 54;
+ }
+ else if (i == 20)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 81;
+ }
+ else if (i == 21)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 108;
+ }
+ else if (i == 22)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 121.5;
+ }
+ else if (i == 23)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 135;
+ }
+ else if (i == 24)
+ {
+ DataRate = StringValue ("HtMcs0");
+ datarate = 15;
+ }
+ else if (i == 25)
+ {
+ DataRate = StringValue ("HtMcs1");
+ datarate = 30;
+ }
+ else if (i == 26)
+ {
+ DataRate = StringValue ("HtMcs2");
+ datarate = 45;
+ }
+ else if (i == 27)
+ {
+ DataRate = StringValue ("HtMcs3");
+ datarate = 60;
+ }
+ else if (i == 28)
+ {
+ DataRate = StringValue ("HtMcs4");
+ datarate = 90;
+ }
+ else if (i == 29)
+ {
+ DataRate = StringValue ("HtMcs5");
+ datarate = 120;
+ }
+ else if (i == 30)
+ {
+ DataRate = StringValue ("HtMcs6");
+ datarate = 135;
+ }
+ else if (i == 31)
+ {
+ DataRate = StringValue ("HtMcs7");
+ datarate = 150;
+ }
+ else if (i == 32)
+ {
+ DataRate = StringValue ("HtMcs8");
+ datarate = 13;
+ }
+ else if (i == 33)
+ {
+ DataRate = StringValue ("HtMcs9");
+ datarate = 26;
+ }
+ else if (i == 34)
+ {
+ DataRate = StringValue ("HtMcs10");
+ datarate = 39;
+ }
+ else if (i == 35)
+ {
+ DataRate = StringValue ("HtMcs11");
+ datarate = 52;
+ }
+ else if (i == 36)
+ {
+ DataRate = StringValue ("HtMcs12");
+ datarate = 78;
+ }
+ else if (i == 37)
+ {
+ DataRate = StringValue ("HtMcs13");
+ datarate = 104;
+ }
+ else if (i == 38)
+ {
+ DataRate = StringValue ("HtMcs14");
+ datarate = 117;
+ }
+ else if (i == 39)
+ {
+ DataRate = StringValue ("HtMcs15");
+ datarate = 130;
+ }
+ else if (i == 40)
+ {
+ DataRate = StringValue ("HtMcs8");
+ datarate = 14.4;
+ }
+ else if (i == 41)
+ {
+ DataRate = StringValue ("HtMcs9");
+ datarate = 28.9;
+ }
+ else if (i == 42)
+ {
+ DataRate = StringValue ("HtMcs10");
+ datarate = 43.3;
+ }
+ else if (i == 43)
+ {
+ DataRate = StringValue ("HtMcs11");
+ datarate = 57.8;
+ }
+ else if (i == 44)
+ {
+ DataRate = StringValue ("HtMcs12");
+ datarate = 86.7;
+ }
+ else if (i == 45)
+ {
+ DataRate = StringValue ("HtMcs13");
+ datarate = 115.6;
+ }
+ else if (i == 46)
+ {
+ DataRate = StringValue ("HtMcs14");
+ datarate = 130.3;
+ }
+ else if (i == 47)
+ {
+ DataRate = StringValue ("HtMcs15");
+ datarate = 144.4;
+ }
+ else if (i == 48)
+ {
+ DataRate = StringValue ("HtMcs8");
+ datarate = 27;
+ }
+ else if (i == 49)
+ {
+ DataRate = StringValue ("HtMcs9");
+ datarate = 54;
+ }
+ else if (i == 50)
+ {
+ DataRate = StringValue ("HtMcs10");
+ datarate = 81;
+ }
+ else if (i == 51)
+ {
+ DataRate = StringValue ("HtMcs11");
+ datarate = 108;
+ }
+ else if (i == 52)
+ {
+ DataRate = StringValue ("HtMcs12");
+ datarate = 162;
+ }
+ else if (i == 53)
+ {
+ DataRate = StringValue ("HtMcs13");
+ datarate = 216;
+ }
+ else if (i == 54)
+ {
+ DataRate = StringValue ("HtMcs14");
+ datarate = 243;
+ }
+ else if (i == 55)
+ {
+ DataRate = StringValue ("HtMcs15");
+ datarate = 270;
+ }
+ else if (i == 56)
+ {
+ DataRate = StringValue ("HtMcs8");
+ datarate = 30;
+ }
+ else if (i == 57)
+ {
+ DataRate = StringValue ("HtMcs9");
+ datarate = 60;
+ }
+ else if (i == 58)
+ {
+ DataRate = StringValue ("HtMcs10");
+ datarate = 90;
+ }
+ else if (i == 59)
+ {
+ DataRate = StringValue ("HtMcs11");
+ datarate = 120;
+ }
+ else if (i == 60)
+ {
+ DataRate = StringValue ("HtMcs12");
+ datarate = 180;
+ }
+ else if (i == 61)
+ {
+ DataRate = StringValue ("HtMcs13");
+ datarate = 240;
+ }
+ else if (i == 62)
+ {
+ DataRate = StringValue ("HtMcs14");
+ datarate = 270;
+ }
+ else if (i == 63)
+ {
+ DataRate = StringValue ("HtMcs15");
+ datarate = 300;
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Illegal index i " << i);
+ }
+
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
+ "ControlMode", DataRate);
+
+ NetDeviceContainer staDevice;
+ NetDeviceContainer apDevice;
+
+ if (wifiType == "ns3::YansWifiPhy")
+ {
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+ staDevice = wifi.Install (phy, mac, wifiStaNode);
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+ apDevice = wifi.Install (phy, mac, wifiApNode);
+
+ }
+ else if (wifiType == "ns3::SpectrumWifiPhy")
+ {
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+ staDevice = wifi.Install (spectrumPhy, mac, wifiStaNode);
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+ apDevice = wifi.Install (spectrumPhy, mac, wifiApNode);
+ }
+
+ // Channel width must be set *after* installation because the attribute
+ // is overwritten by the ConfigureStandard method ()
+ Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", UintegerValue (channelWidth));
+
+ // mobility.
+ MobilityHelper mobility;
+ Ptr positionAlloc = CreateObject ();
+
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (distance, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+ mobility.Install (wifiApNode);
+ mobility.Install (wifiStaNode);
+
+ /* Internet stack*/
+ InternetStackHelper stack;
+ stack.Install (wifiApNode);
+ stack.Install (wifiStaNode);
+
+ Ipv4AddressHelper address;
+
+ address.SetBase ("192.168.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer staNodeInterface;
+ Ipv4InterfaceContainer apNodeInterface;
+
+ staNodeInterface = address.Assign (staDevice);
+ apNodeInterface = address.Assign (apDevice);
+
+ /* Setting applications */
+ ApplicationContainer serverApp, sinkApp;
+ //UDP flow
+ UdpServerHelper myServer (9);
+ serverApp = myServer.Install (wifiStaNode.Get (0));
+ serverApp.Start (Seconds (0.0));
+ serverApp.Stop (Seconds (simulationTime + 1));
+
+ UdpClientHelper myClient (staNodeInterface.GetAddress (0), 9);
+ myClient.SetAttribute ("MaxPackets", UintegerValue (4294967295u));
+ myClient.SetAttribute ("Interval", TimeValue (Time ("0.00002"))); //packets/s
+ myClient.SetAttribute ("PacketSize", UintegerValue (payloadSize));
+
+ ApplicationContainer clientApp = myClient.Install (wifiApNode.Get (0));
+ clientApp.Start (Seconds (1.0));
+ clientApp.Stop (Seconds (simulationTime + 1));
+
+ if (enablePcap)
+ {
+ std::stringstream ss;
+ ss << "wifi-spectrum-saturation-example-" << i;
+ phy.EnablePcap (ss.str (), apDevice);
+ }
+
+ Simulator::Stop (Seconds (simulationTime + 1));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ double throughput;
+ uint32_t totalPacketsThrough;
+ totalPacketsThrough = DynamicCast (serverApp.Get (0))->GetReceived ();
+ throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
+ std::cout << std::setw (5) << i <<
+ std::setw (6) << (i % 8) + 8 * (i / 32) <<
+ std::setw (8) << channelWidth <<
+ std::setw (10) << datarate <<
+ std::setw (12) << throughput <<
+ std::setw (8) << totalPacketsThrough <<
+ std::endl;
+ }
+ return 0;
+}
diff --git a/examples/wireless/wscript b/examples/wireless/wscript
index 9d093e808..8459450db 100644
--- a/examples/wireless/wscript
+++ b/examples/wireless/wscript
@@ -91,3 +91,11 @@ def build(bld):
obj = bld.create_ns3_program('80211e-txop', ['internet', 'mobility', 'wifi', 'applications'])
obj.source = '80211e-txop.cc'
+ obj = bld.create_ns3_program('wifi-spectrum-per-example', ['internet', 'mobility', 'wifi', 'applications', 'spectrum'])
+ obj.source = 'wifi-spectrum-per-example.cc'
+
+ obj = bld.create_ns3_program('wifi-spectrum-per-interference', ['internet', 'mobility', 'wifi', 'applications', 'spectrum'])
+ obj.source = 'wifi-spectrum-per-interference.cc'
+
+ obj = bld.create_ns3_program('wifi-spectrum-saturation-example', ['internet', 'mobility', 'wifi', 'applications', 'spectrum'])
+ obj.source = 'wifi-spectrum-saturation-example.cc'
diff --git a/src/spectrum/model/wifi-spectrum-value-helper.cc b/src/spectrum/model/wifi-spectrum-value-helper.cc
index 3a9f0fb43..54f8d39d4 100644
--- a/src/spectrum/model/wifi-spectrum-value-helper.cc
+++ b/src/spectrum/model/wifi-spectrum-value-helper.cc
@@ -1,6 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 CTTC
+ * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
*
* 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
@@ -16,14 +17,350 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Nicola Baldo
+ * Giuseppe Piro
*/
-
+#include