--- a/examples/wireless/ht-wifi-network.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/ht-wifi-network.cc Thu Sep 03 22:16:49 2015 +0200
@@ -3,7 +3,7 @@
* Copyright (c) 2009 MIRKO BANCHI
*
* 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
+ * 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,
@@ -53,325 +53,163 @@
cmd.AddValue ("udp", "UDP if set to 1, TCP otherwise", udp);
cmd.Parse (argc,argv);
- std::cout << "DataRate" << "\t" << "Throughput" << '\n';
- for (int i = 0; i <= 31; i++)
+ std::cout << "MCS value" << "\t\t" << "Channel width" << "\t\t" << "short GI" << "\t\t" << "Throughput" << '\n';
+ for (int i = 0; i <= 7; i++) //MCS
{
- uint32_t payloadSize; //1500 byte IP packet
- if (udp)
- {
- payloadSize = 1472; //bytes
- }
- else
- {
- payloadSize = 1448; //bytes
- Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
- }
-
- NodeContainer wifiStaNode;
- wifiStaNode.Create (1);
- NodeContainer wifiApNode;
- wifiApNode.Create (1);
-
- YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
- YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
- phy.SetChannel (channel.Create ());
-
- if (i <= 7)
- {
- phy.Set ("ShortGuardEnabled", BooleanValue (false));
- phy.Set ("ChannelBonding", BooleanValue (false));
- }
- else if (i > 7 && i <= 15)
- {
- phy.Set ("ShortGuardEnabled", BooleanValue (true));
- phy.Set ("ChannelBonding", BooleanValue (false));
- }
- else if (i > 15 && i <= 23)
- {
- phy.Set ("ShortGuardEnabled", BooleanValue (false));
- phy.Set ("ChannelBonding", BooleanValue (true));
- }
- else
- {
- phy.Set ("ShortGuardEnabled", BooleanValue (true));
- phy.Set ("ChannelBonding", BooleanValue (true));
- }
-
- WifiHelper wifi = WifiHelper::Default ();
- wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
- HtWifiMacHelper mac = HtWifiMacHelper::Default ();
-
- Ssid ssid = Ssid ("ns380211n");
-
- double datarate = 0;
- StringValue DataRate;
- if (i == 0)
- {
- DataRate = StringValue ("OfdmRate6_5MbpsBW20MHz");
- datarate = 6.5;
- }
- else if (i == 1)
- {
- DataRate = StringValue ("OfdmRate13MbpsBW20MHz");
- datarate = 13;
- }
- else if (i == 2)
- {
- DataRate = StringValue ("OfdmRate19_5MbpsBW20MHz");
- datarate = 19.5;
- }
- else if (i == 3)
- {
- DataRate = StringValue ("OfdmRate26MbpsBW20MHz");
- datarate = 26;
- }
- else if (i == 4)
- {
- DataRate = StringValue ("OfdmRate39MbpsBW20MHz");
- datarate = 39;
- }
- else if (i == 5)
- {
- DataRate = StringValue ("OfdmRate52MbpsBW20MHz");
- datarate = 52;
- }
- else if (i == 6)
- {
- DataRate = StringValue ("OfdmRate58_5MbpsBW20MHz");
- datarate = 58.5;
- }
- else if (i == 7)
- {
- DataRate = StringValue ("OfdmRate65MbpsBW20MHz");
- datarate = 65;
- }
- else if (i == 8)
- {
- DataRate = StringValue ("OfdmRate7_2MbpsBW20MHz");
- datarate = 7.2;
- }
- else if (i == 9)
- {
- DataRate = StringValue ("OfdmRate14_4MbpsBW20MHz");
- datarate = 14.4;
- }
- else if (i == 10)
- {
- DataRate = StringValue ("OfdmRate21_7MbpsBW20MHz");
- datarate = 21.7;
- }
- else if (i == 11)
- {
- DataRate = StringValue ("OfdmRate28_9MbpsBW20MHz");
- datarate = 28.9;
- }
- else if (i == 12)
- {
- DataRate = StringValue ("OfdmRate43_3MbpsBW20MHz");
- datarate = 43.3;
- }
- else if (i == 13)
- {
- DataRate = StringValue ("OfdmRate57_8MbpsBW20MHz");
- datarate = 57.8;
- }
- else if (i == 14)
- {
- DataRate = StringValue ("OfdmRate65MbpsBW20MHzShGi");
- datarate = 65;
- }
- else if (i == 15)
- {
- DataRate = StringValue ("OfdmRate72_2MbpsBW20MHz");
- datarate = 72.2;
- }
- else if (i == 16)
- {
- DataRate = StringValue ("OfdmRate13_5MbpsBW40MHz");
- datarate = 13.5;
- }
- else if (i == 17)
- {
- DataRate = StringValue ("OfdmRate27MbpsBW40MHz");
- datarate = 27;
- }
- else if (i == 18)
- {
- DataRate = StringValue ("OfdmRate40_5MbpsBW40MHz");
- datarate = 40.5;
- }
- else if (i == 19)
- {
- DataRate = StringValue ("OfdmRate54MbpsBW40MHz");
- datarate = 54;
- }
- else if (i == 20)
- {
- DataRate = StringValue ("OfdmRate81MbpsBW40MHz");
- datarate = 81;
- }
- else if (i == 21)
+ for (int j = 20; j <= 40; ) //channel width
{
- DataRate = StringValue ("OfdmRate108MbpsBW40MHz");
- datarate = 108;
- }
- else if (i == 22)
- {
- DataRate = StringValue ("OfdmRate121_5MbpsBW40MHz");
- datarate = 121.5;
- }
- else if (i == 23)
- {
- DataRate = StringValue ("OfdmRate135MbpsBW40MHz");
- datarate = 135;
- }
- else if (i == 24)
- {
- DataRate = StringValue ("OfdmRate15MbpsBW40MHz");
- datarate = 15;
- }
- else if (i == 25)
- {
- DataRate = StringValue ("OfdmRate30MbpsBW40MHz");
- datarate = 30;
- }
- else if (i == 26)
- {
- DataRate = StringValue ("OfdmRate45MbpsBW40MHz");
- datarate = 45;
- }
- else if (i == 27)
- {
- DataRate = StringValue ("OfdmRate60MbpsBW40MHz");
- datarate = 60;
- }
- else if (i == 28)
- {
- DataRate = StringValue ("OfdmRate90MbpsBW40MHz");
- datarate = 90;
- }
- else if (i == 29)
- {
- DataRate = StringValue ("OfdmRate120MbpsBW40MHz");
- datarate = 120;
- }
- else if (i == 30)
- {
- DataRate = StringValue ("OfdmRate135MbpsBW40MHzShGi");
- datarate = 135;
- }
- else
- {
- DataRate = StringValue ("OfdmRate150MbpsBW40MHz");
- datarate = 150;
- }
+ for (int k = 0; k < 2; k++) //GI: 0 and 1
+ {
+ uint32_t payloadSize; //1500 byte IP packet
+ if (udp)
+ {
+ payloadSize = 1472; //bytes
+ }
+ else
+ {
+ payloadSize = 1448; //bytes
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
+ }
+
+ NodeContainer wifiStaNode;
+ wifiStaNode.Create (1);
+ NodeContainer wifiApNode;
+ wifiApNode.Create (1);
+
+ YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
+ YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+ phy.SetChannel (channel.Create ());
+
+ // Set guard interval
+ phy.Set ("ShortGuardEnabled", BooleanValue (k));
+
+ WifiHelper wifi = WifiHelper::Default ();
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
+ HtWifiMacHelper mac = HtWifiMacHelper::Default ();
+
+ Ssid ssid = Ssid ("ns380211n");
+
+ std::stringstream sstmp;
+ std::string strtmp, dataRate;
+ StringValue DataRate;
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
- "ControlMode", DataRate);
- mac.SetType ("ns3::StaWifiMac",
- "Ssid", SsidValue (ssid),
- "ActiveProbing", BooleanValue (false));
+ sstmp << i;
+ sstmp >> strtmp;
+ dataRate = "HtMcs" + strtmp;
+ DataRate = StringValue (dataRate);
- NetDeviceContainer staDevice;
- staDevice = wifi.Install (phy, mac, wifiStaNode);
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
+ "ControlMode", DataRate);
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
- mac.SetType ("ns3::ApWifiMac",
- "Ssid", SsidValue (ssid));
+ NetDeviceContainer staDevice;
+ staDevice = wifi.Install (phy, mac, wifiStaNode);
+
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+
+ NetDeviceContainer apDevice;
+ apDevice = wifi.Install (phy, mac, wifiApNode);
- NetDeviceContainer apDevice;
- apDevice = wifi.Install (phy, mac, wifiApNode);
+ // Set channel width
+ Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", UintegerValue (j));
+
+ // mobility.
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
- // mobility.
- MobilityHelper mobility;
- Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (1.0, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
- positionAlloc->Add (Vector (0.0, 0.0, 0.0));
- positionAlloc->Add (Vector (1.0, 0.0, 0.0));
- mobility.SetPositionAllocator (positionAlloc);
+ mobility.Install (wifiApNode);
+ mobility.Install (wifiStaNode);
- mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ /* Internet stack*/
+ InternetStackHelper stack;
+ stack.Install (wifiApNode);
+ stack.Install (wifiStaNode);
- mobility.Install (wifiApNode);
- mobility.Install (wifiStaNode);
+ Ipv4AddressHelper address;
- /* Internet stack*/
- InternetStackHelper stack;
- stack.Install (wifiApNode);
- stack.Install (wifiStaNode);
+ address.SetBase ("192.168.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer staNodeInterface;
+ Ipv4InterfaceContainer apNodeInterface;
+
+ staNodeInterface = address.Assign (staDevice);
+ apNodeInterface = address.Assign (apDevice);
- Ipv4AddressHelper address;
+ /* 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));
- address.SetBase ("192.168.1.0", "255.255.255.0");
- Ipv4InterfaceContainer staNodeInterface;
- Ipv4InterfaceContainer apNodeInterface;
+ UdpClientHelper myClient (staNodeInterface.GetAddress (0), 9);
+ myClient.SetAttribute ("MaxPackets", UintegerValue (4294967295u));
+ myClient.SetAttribute ("Interval", TimeValue (Time ("0.00001"))); //packets/s
+ myClient.SetAttribute ("PacketSize", UintegerValue (payloadSize));
- staNodeInterface = address.Assign (staDevice);
- apNodeInterface = address.Assign (apDevice);
+ 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));
- /* 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));
+ 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));
+ }
+
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
- 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));
+ Simulator::Stop (Seconds (simulationTime + 1));
+ Simulator::Run ();
+ Simulator::Destroy ();
- ApplicationContainer clientApp = myClient.Install (wifiApNode.Get (0));
- clientApp.Start (Seconds (1.0));
- clientApp.Stop (Seconds (simulationTime+1));
+ double throughput = 0;
+ if (udp)
+ {
+ //UDP
+ uint32_t totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
+ throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ else
+ {
+ //TCP
+ uint32_t totalPacketsThrough = DynamicCast<PacketSink> (sinkApp.Get (0))->GetTotalRx ();
+ throughput = totalPacketsThrough * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ std::cout << dataRate << "\t\t\t" << j << " MHz\t\t\t" << k << "\t\t\t" << throughput << " Mbit/s" << std::endl;
+ }
+ j *= 2;
}
- 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));
- }
-
- Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
-
- Simulator::Stop (Seconds (simulationTime+1));
- Simulator::Run ();
- Simulator::Destroy ();
-
- double throughput = 0;
- if (udp)
- {
- //UDP
- uint32_t totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
- throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
- }
- else
- {
- //TCP
- uint32_t totalPacketsThrough = DynamicCast<PacketSink> (sinkApp.Get (0))->GetTotalRx ();
- throughput = totalPacketsThrough * 8 / (simulationTime * 1000000.0); //Mbit/s
- }
- std::cout << datarate << "\t\t" << throughput << " Mbit/s" << std::endl;
}
return 0;
}
--- a/examples/wireless/ofdm-ht-validation.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/ofdm-ht-validation.cc Thu Sep 03 22:16:49 2015 +0200
@@ -33,14 +33,15 @@
std::ofstream nistfile ("nist-frame-success-rate-n.plt");
std::vector <std::string> modes;
- modes.push_back ("OfdmRate6_5MbpsBW20MHz");
- modes.push_back ("OfdmRate13MbpsBW20MHz");
- modes.push_back ("OfdmRate19_5MbpsBW20MHz");
- modes.push_back ("OfdmRate26MbpsBW20MHz");
- modes.push_back ("OfdmRate39MbpsBW20MHz");
- modes.push_back ("OfdmRate52MbpsBW20MHz");
- modes.push_back ("OfdmRate58_5MbpsBW20MHz");
- modes.push_back ("OfdmRate65MbpsBW20MHz");
+ modes.push_back ("HtMcs0");
+ modes.push_back ("HtMcs1");
+ modes.push_back ("HtMcs2");
+ modes.push_back ("HtMcs3");
+ modes.push_back ("HtMcs4");
+ modes.push_back ("HtMcs5");
+ modes.push_back ("HtMcs6");
+ modes.push_back ("HtMcs7");
+
CommandLine cmd;
cmd.AddValue ("FrameSize", "The frame size", FrameSize);
@@ -48,6 +49,7 @@
Gnuplot yansplot = Gnuplot ("yans-frame-success-rate-n.eps");
Gnuplot nistplot = Gnuplot ("nist-frame-success-rate-n.eps");
+ WifiTxVector txVector;
Ptr <YansErrorRateModel> yans = CreateObject<YansErrorRateModel> ();
Ptr <NistErrorRateModel> nist = CreateObject<NistErrorRateModel> ();
@@ -57,12 +59,13 @@
std::cout << modes[i] << std::endl;
Gnuplot2dDataset yansdataset (modes[i]);
Gnuplot2dDataset nistdataset (modes[i]);
+ txVector.SetMode (modes[i]);
for (double snr = -5.0; snr <= 30.0; snr += 0.1)
{
- double ps = yans->GetChunkSuccessRate (WifiMode (modes[i]), std::pow (10.0,snr / 10.0), FrameSize * 8);
+ double ps = yans->GetChunkSuccessRate (WifiMode (modes[i]), txVector, std::pow (10.0,snr / 10.0), FrameSize * 8);
yansdataset.Add (snr, ps);
- ps = nist->GetChunkSuccessRate (WifiMode (modes[i]), std::pow (10.0,snr / 10.0), FrameSize * 8);
+ ps = nist->GetChunkSuccessRate (WifiMode (modes[i]), txVector, std::pow (10.0,snr / 10.0), FrameSize * 8);
nistdataset.Add (snr, ps);
}
--- a/examples/wireless/ofdm-validation.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/ofdm-validation.cc Thu Sep 03 22:16:49 2015 +0200
@@ -53,18 +53,20 @@
Ptr <YansErrorRateModel> yans = CreateObject<YansErrorRateModel> ();
Ptr <NistErrorRateModel> nist = CreateObject<NistErrorRateModel> ();
+ WifiTxVector txVector;
for (uint32_t i = 0; i < modes.size (); i++)
{
std::cout << modes[i] << std::endl;
Gnuplot2dDataset yansdataset (modes[i]);
Gnuplot2dDataset nistdataset (modes[i]);
+ txVector.SetMode (modes[i]);
for (double snr = -5.0; snr <= 30.0; snr += 0.1)
{
- double ps = yans->GetChunkSuccessRate (WifiMode (modes[i]), std::pow (10.0,snr/10.0), FrameSize*8);
+ double ps = yans->GetChunkSuccessRate (WifiMode (modes[i]), txVector, std::pow (10.0,snr / 10.0), FrameSize * 8);
yansdataset.Add (snr, ps);
- ps = nist->GetChunkSuccessRate (WifiMode (modes[i]), std::pow (10.0,snr/10.0), FrameSize*8);
+ ps = nist->GetChunkSuccessRate (WifiMode (modes[i]), txVector, std::pow (10.0,snr / 10.0), FrameSize * 8);
nistdataset.Add (snr, ps);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/wireless/ofdm-vht-validation.cc Thu Sep 03 22:16:49 2015 +0200
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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: Sébastien Deronne <sebastien.deronne@gmail.com>
+ */
+#include "ns3/core-module.h"
+#include "ns3/yans-error-rate-model.h"
+#include "ns3/nist-error-rate-model.h"
+#include "ns3/gnuplot.h"
+
+#include <fstream>
+#include <vector>
+#include <cmath>
+
+using namespace ns3;
+
+int main (int argc, char *argv[])
+{
+ uint32_t FrameSize = 2000; //bytes
+ std::ofstream yansfile ("yans-frame-success-rate-n.plt");
+ std::ofstream nistfile ("nist-frame-success-rate-n.plt");
+ std::vector <std::string> modes;
+
+ modes.push_back ("VhtMcs0");
+ modes.push_back ("VhtMcs1");
+ modes.push_back ("VhtMcs2");
+ modes.push_back ("VhtMcs3");
+ modes.push_back ("VhtMcs4");
+ modes.push_back ("VhtMcs5");
+ modes.push_back ("VhtMcs6");
+ modes.push_back ("VhtMcs7");
+ modes.push_back ("VhtMcs8");
+
+ CommandLine cmd;
+ cmd.AddValue ("FrameSize", "The frame size", FrameSize);
+ cmd.Parse (argc, argv);
+
+ Gnuplot yansplot = Gnuplot ("yans-frame-success-rate-n.eps");
+ Gnuplot nistplot = Gnuplot ("nist-frame-success-rate-n.eps");
+
+ Ptr <YansErrorRateModel> yans = CreateObject<YansErrorRateModel> ();
+ Ptr <NistErrorRateModel> nist = CreateObject<NistErrorRateModel> ();
+ WifiTxVector txVector;
+
+ for (uint32_t i = 0; i < modes.size (); i++)
+ {
+ std::cout << modes[i] << std::endl;
+ Gnuplot2dDataset yansdataset (modes[i]);
+ Gnuplot2dDataset nistdataset (modes[i]);
+ txVector.SetMode (modes[i]);
+
+ for (double snr = -5.0; snr <= 30.0; snr += 0.1)
+ {
+ double ps = yans->GetChunkSuccessRate (WifiMode (modes[i]), txVector, std::pow (10.0,snr / 10.0), FrameSize * 8);
+ yansdataset.Add (snr, ps);
+ ps = nist->GetChunkSuccessRate (WifiMode (modes[i]), txVector, std::pow (10.0,snr / 10.0), FrameSize * 8);
+ nistdataset.Add (snr, ps);
+ }
+
+ yansplot.AddDataset (yansdataset);
+ nistplot.AddDataset (nistdataset);
+ }
+
+ yansplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
+ yansplot.SetLegend ("SNR(dB)", "Frame Success Rate");
+ yansplot.SetExtra ("set xrange [-5:55]\n\
+set yrange [0:1]\n\
+set style line 1 linewidth 5\n\
+set style line 2 linewidth 5\n\
+set style line 3 linewidth 5\n\
+set style line 4 linewidth 5\n\
+set style line 5 linewidth 5\n\
+set style line 6 linewidth 5\n\
+set style line 7 linewidth 5\n\
+set style line 8 linewidth 5\n\
+set style line 9 linewidth 5\n\
+set style increment user" );
+ yansplot.GenerateOutput (yansfile);
+ yansfile.close ();
+
+ nistplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
+ nistplot.SetLegend ("SNR(dB)", "Frame Success Rate");
+ nistplot.SetExtra ("set xrange [-5:55]\n\
+set yrange [0:1]\n\
+set style line 1 linewidth 5\n\
+set style line 2 linewidth 5\n\
+set style line 3 linewidth 5\n\
+set style line 4 linewidth 5\n\
+set style line 5 linewidth 5\n\
+set style line 6 linewidth 5\n\
+set style line 7 linewidth 5\n\
+set style line 8 linewidth 5\n\
+set style line 9 linewidth 5\n\
+set style increment user" );
+
+ nistplot.GenerateOutput (nistfile);
+ nistfile.close ();
+}
+
--- a/examples/wireless/simple-ht-hidden-stations.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/simple-ht-hidden-stations.cc Thu Sep 03 22:16:49 2015 +0200
@@ -53,39 +53,43 @@
uint64_t simulationTime = 10; //seconds
uint32_t nMpdus = 1;
bool enableRts = 0;
-
+
CommandLine cmd;
- cmd.AddValue("nMpdus", "Number of aggregated MPDUs", nMpdus);
- cmd.AddValue("payloadSize", "Payload size in bytes", payloadSize);
- cmd.AddValue("enableRts", "Enable RTS/CTS", enableRts); // 1: RTS/CTS enabled; 0: RTS/CTS disabled
- cmd.AddValue("simulationTime", "Simulation time in seconds", simulationTime);
+ cmd.AddValue ("nMpdus", "Number of aggregated MPDUs", nMpdus);
+ cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize);
+ cmd.AddValue ("enableRts", "Enable RTS/CTS", enableRts); // 1: RTS/CTS enabled; 0: RTS/CTS disabled
+ cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
cmd.Parse (argc, argv);
-
- if(!enableRts)
- Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("999999"));
+
+ if (!enableRts)
+ {
+ Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("999999"));
+ }
else
- Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("0"));
-
+ {
+ Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("0"));
+ }
+
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("990000"));
-
+
// Set the maximum wireless range to 5 meters in order to reproduce a hidden nodes scenario, i.e. the distance between hidden stations is larger than 5 meters
Config::SetDefault ("ns3::RangePropagationLossModel::MaxRange", DoubleValue (5));
NodeContainer wifiStaNodes;
wifiStaNodes.Create (2);
NodeContainer wifiApNode;
- wifiApNode.Create(1);
+ wifiApNode.Create (1);
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
channel.AddPropagationLoss ("ns3::RangePropagationLossModel"); //wireless range limited to 5 meters!
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
phy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
- phy.SetChannel (channel.Create());
+ phy.SetChannel (channel.Create ());
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue("OfdmRate65MbpsBW20MHz"), "ControlMode", StringValue("OfdmRate6_5MbpsBW20MHz"));
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("HtMcs7"), "ControlMode", StringValue ("HtMcs0"));
HtWifiMacHelper mac = HtWifiMacHelper::Default ();
Ssid ssid = Ssid ("simple-mpdu-aggregation");
@@ -93,25 +97,31 @@
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
- if (nMpdus > 1) mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled
+ if (nMpdus > 1)
+ {
+ mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled
+ }
mac.SetMpduAggregatorForAc (AC_BE,"ns3::MpduStandardAggregator",
- "MaxAmpduSize", UintegerValue (nMpdus*(payloadSize+100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes,
- //i.e. nMpdus aggregated packets in an A-MPDU
-
+ "MaxAmpduSize", UintegerValue (nMpdus * (payloadSize + 100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes,
+ //i.e. nMpdus aggregated packets in an A-MPDU
+
NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes);
mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid),
- "BeaconInterval", TimeValue (MicroSeconds(102400)),
+ "BeaconInterval", TimeValue (MicroSeconds (102400)),
"BeaconGeneration", BooleanValue (true));
- if (nMpdus > 1) mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled
-
+ if (nMpdus > 1)
+ {
+ mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled
+
+ }
mac.SetMpduAggregatorForAc (AC_BE,"ns3::MpduStandardAggregator",
- "MaxAmpduSize", UintegerValue (nMpdus*(payloadSize+100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes,
- //i.e. nMpdus aggregated packets in an A-MPDU
+ "MaxAmpduSize", UintegerValue (nMpdus * (payloadSize + 100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes,
+ //i.e. nMpdus aggregated packets in an A-MPDU
NetDeviceContainer apDevice;
apDevice = wifi.Install (phy, mac, wifiApNode);
@@ -145,35 +155,35 @@
StaInterface = address.Assign (staDevices);
Ipv4InterfaceContainer ApInterface;
ApInterface = address.Assign (apDevice);
-
+
// Setting applications
UdpServerHelper myServer (9);
ApplicationContainer serverApp = myServer.Install (wifiApNode);
serverApp.Start (Seconds (0.0));
- serverApp.Stop (Seconds (simulationTime+1));
-
+ serverApp.Stop (Seconds (simulationTime + 1));
+
UdpClientHelper myClient (ApInterface.GetAddress (0), 9);
myClient.SetAttribute ("MaxPackets", UintegerValue (4294967295u));
myClient.SetAttribute ("Interval", TimeValue (Time ("0.00002"))); //packets/s
myClient.SetAttribute ("PacketSize", UintegerValue (payloadSize));
-
+
// Saturated UDP traffic from stations to AP
ApplicationContainer clientApp1 = myClient.Install (wifiStaNodes);
clientApp1.Start (Seconds (1.0));
- clientApp1.Stop (Seconds (simulationTime+1));
-
+ clientApp1.Stop (Seconds (simulationTime + 1));
+
phy.EnablePcap ("SimpleHtHiddenStations_Ap", apDevice.Get (0));
phy.EnablePcap ("SimpleHtHiddenStations_Sta1", staDevices.Get (0));
phy.EnablePcap ("SimpleHtHiddenStations_Sta2", staDevices.Get (1));
-
- Simulator::Stop (Seconds (simulationTime+1));
+
+ Simulator::Stop (Seconds (simulationTime + 1));
Simulator::Run ();
Simulator::Destroy ();
-
- uint32_t totalPacketsThrough = DynamicCast<UdpServer>(serverApp.Get (0))->GetReceived ();
- double throughput = totalPacketsThrough*payloadSize*8/(simulationTime*1000000.0);
+
+ uint32_t totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
+ double throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0);
std::cout << "Throughput: " << throughput << " Mbit/s" << '\n';
-
+
return 0;
}
--- a/examples/wireless/simple-mpdu-aggregation.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/simple-mpdu-aggregation.cc Thu Sep 03 22:16:49 2015 +0200
@@ -56,34 +56,38 @@
uint64_t simulationTime = 10; //seconds
uint32_t nMpdus = 1;
bool enableRts = 0;
-
+
CommandLine cmd;
- cmd.AddValue("nMpdus", "Number of aggregated MPDUs", nMpdus); //number of aggregated MPDUs specified by the user
- cmd.AddValue("payloadSize", "Payload size in bytes", payloadSize);
- cmd.AddValue("enableRts", "Enable RTS/CTS", enableRts);
- cmd.AddValue("simulationTime", "Simulation time in seconds", simulationTime);
+ cmd.AddValue ("nMpdus", "Number of aggregated MPDUs", nMpdus); //number of aggregated MPDUs specified by the user
+ cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize);
+ cmd.AddValue ("enableRts", "Enable RTS/CTS", enableRts);
+ cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
cmd.Parse (argc, argv);
-
- if(!enableRts)
- Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("999999"));
+
+ if (!enableRts)
+ {
+ Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("999999"));
+ }
else
- Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("0"));
-
+ {
+ Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("0"));
+ }
+
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("990000"));
NodeContainer wifiStaNode;
wifiStaNode.Create (1);
NodeContainer wifiApNode;
- wifiApNode.Create(1);
+ wifiApNode.Create (1);
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
phy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
- phy.SetChannel (channel.Create());
+ phy.SetChannel (channel.Create ());
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue("OfdmRate65MbpsBW20MHz"), "ControlMode", StringValue("OfdmRate6_5MbpsBW20MHz"));
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("HtMcs7"), "ControlMode", StringValue ("HtMcs0"));
HtWifiMacHelper mac = HtWifiMacHelper::Default ();
Ssid ssid = Ssid ("simple-mpdu-aggregation");
@@ -91,23 +95,29 @@
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
- if (nMpdus > 1) mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled (i.e. nMpdus > 1)
+ if (nMpdus > 1)
+ {
+ mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled (i.e. nMpdus > 1)
+ }
mac.SetMpduAggregatorForAc (AC_BE,"ns3::MpduStandardAggregator",
- "MaxAmpduSize", UintegerValue (nMpdus*(payloadSize+100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes, i.e. nMpdus aggregated packets in an A-MPDU
-
+ "MaxAmpduSize", UintegerValue (nMpdus * (payloadSize + 100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes, i.e. nMpdus aggregated packets in an A-MPDU
+
NetDeviceContainer staDevice;
staDevice = wifi.Install (phy, mac, wifiStaNode);
mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid),
- "BeaconInterval", TimeValue (MicroSeconds(102400)),
+ "BeaconInterval", TimeValue (MicroSeconds (102400)),
"BeaconGeneration", BooleanValue (true));
- if (nMpdus > 1) mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled (i.e. nMpdus > 1)
-
+ if (nMpdus > 1)
+ {
+ mac.SetBlockAckThresholdForAc (AC_BE, 2); //enable Block ACK when A-MPDU is enabled (i.e. nMpdus > 1)
+
+ }
mac.SetMpduAggregatorForAc (AC_BE,"ns3::MpduStandardAggregator",
- "MaxAmpduSize", UintegerValue (nMpdus*(payloadSize+100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes, i.e. nMpdus aggregated packets in an A-MPDU
+ "MaxAmpduSize", UintegerValue (nMpdus * (payloadSize + 100))); //enable MPDU aggregation for AC_BE with a maximum aggregated size of nMpdus*(payloadSize+100) bytes, i.e. nMpdus aggregated packets in an A-MPDU
NetDeviceContainer apDevice;
apDevice = wifi.Install (phy, mac, wifiApNode);
@@ -137,30 +147,30 @@
StaInterface = address.Assign (staDevice);
Ipv4InterfaceContainer ApInterface;
ApInterface = address.Assign (apDevice);
-
+
/* Setting applications */
UdpServerHelper myServer (9);
ApplicationContainer serverApp = myServer.Install (wifiStaNode.Get (0));
serverApp.Start (Seconds (0.0));
- serverApp.Stop (Seconds (simulationTime+1));
-
+ serverApp.Stop (Seconds (simulationTime + 1));
+
UdpClientHelper myClient (StaInterface.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));
-
- Simulator::Stop (Seconds (simulationTime+1));
+ clientApp.Stop (Seconds (simulationTime + 1));
+
+ Simulator::Stop (Seconds (simulationTime + 1));
Simulator::Run ();
Simulator::Destroy ();
-
- uint32_t totalPacketsThrough = DynamicCast<UdpServer>(serverApp.Get (0))->GetReceived ();
- double throughput = totalPacketsThrough*payloadSize*8/(simulationTime*1000000.0);
+
+ uint32_t totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
+ double throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0);
std::cout << "Throughput: " << throughput << " Mbit/s" << '\n';
-
+
return 0;
}
--- a/examples/wireless/simple-msdu-aggregation.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/simple-msdu-aggregation.cc Thu Sep 03 22:16:49 2015 +0200
@@ -3,7 +3,7 @@
* Copyright (c) 2009 MIRKO BANCHI
*
* 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
+ * 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,
@@ -56,105 +56,109 @@
uint64_t simulationTime = 10; //seconds
uint32_t nMsdus = 1;
bool enableRts = 0;
-
+
CommandLine cmd;
- cmd.AddValue("nMsdus", "Number of aggregated MSDUs", nMsdus); //number of aggregated MSDUs specified by the user
- cmd.AddValue("payloadSize", "Payload size in bytes", payloadSize);
- cmd.AddValue("enableRts", "Enable RTS/CTS", enableRts);
- cmd.AddValue("simulationTime", "Simulation time in seconds", simulationTime);
+ cmd.AddValue ("nMsdus", "Number of aggregated MSDUs", nMsdus); //number of aggregated MSDUs specified by the user
+ cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize);
+ cmd.AddValue ("enableRts", "Enable RTS/CTS", enableRts);
+ cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
cmd.Parse (argc, argv);
-
- if(!enableRts)
- Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("999999"));
+
+ if (!enableRts)
+ {
+ Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("999999"));
+ }
else
- Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("0"));
-
+ {
+ Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("0"));
+ }
+
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("990000"));
-
+
NodeContainer wifiStaNode;
wifiStaNode.Create (1);
NodeContainer wifiApNode;
- wifiApNode.Create(1);
-
+ wifiApNode.Create (1);
+
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
phy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
- phy.SetChannel (channel.Create());
-
+ phy.SetChannel (channel.Create ());
+
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue("OfdmRate65MbpsBW20MHz"), "ControlMode", StringValue("OfdmRate6_5MbpsBW20MHz"));
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("HtMcs7"), "ControlMode", StringValue ("HtMcs0"));
HtWifiMacHelper mac = HtWifiMacHelper::Default ();
Ssid ssid = Ssid ("simple-msdu-aggregation");
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
-
- mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator",
- "MaxAmsduSize", UintegerValue (nMsdus*(payloadSize+100))); //enable MSDU aggregation for AC_BE with a maximum aggregated size of nMsdus*(payloadSize+100) bytes, i.e. nMsdus aggregated packets in an A-MSDU
+
+ mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator",
+ "MaxAmsduSize", UintegerValue (nMsdus * (payloadSize + 100))); //enable MSDU aggregation for AC_BE with a maximum aggregated size of nMsdus*(payloadSize+100) bytes, i.e. nMsdus aggregated packets in an A-MSDU
NetDeviceContainer staDevice;
staDevice = wifi.Install (phy, mac, wifiStaNode);
mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));
-
- mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator",
- "MaxAmsduSize", UintegerValue (nMsdus*(payloadSize+100))); //enable MSDU aggregation for AC_BE with a maximum aggregated size of nMsdus*(payloadSize+100) bytes, i.e. nMsdus aggregated packets in an A-MSDU
-
+
+ mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator",
+ "MaxAmsduSize", UintegerValue (nMsdus * (payloadSize + 100))); //enable MSDU aggregation for AC_BE with a maximum aggregated size of nMsdus*(payloadSize+100) bytes, i.e. nMsdus aggregated packets in an A-MSDU
+
NetDeviceContainer apDevice;
apDevice = wifi.Install (phy, mac, wifiApNode);
-
+
/* Setting mobility model */
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
-
+
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (1.0, 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 StaInterface;
StaInterface = address.Assign (staDevice);
Ipv4InterfaceContainer ApInterface;
ApInterface = address.Assign (apDevice);
-
+
/* Setting applications */
UdpServerHelper myServer (9);
ApplicationContainer serverApp = myServer.Install (wifiStaNode.Get (0));
serverApp.Start (Seconds (0.0));
- serverApp.Stop (Seconds (simulationTime+1));
-
+ serverApp.Stop (Seconds (simulationTime + 1));
+
UdpClientHelper myClient (StaInterface.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));
-
- Simulator::Stop (Seconds (simulationTime+1));
-
+ clientApp.Stop (Seconds (simulationTime + 1));
+
+ Simulator::Stop (Seconds (simulationTime + 1));
+
Simulator::Run ();
Simulator::Destroy ();
-
- uint32_t totalPacketsThrough = DynamicCast<UdpServer>(serverApp.Get (0))->GetReceived ();
- double throughput = totalPacketsThrough*payloadSize*8/(simulationTime*1000000.0);
+
+ uint32_t totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
+ double throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0);
std::cout << "Throughput: " << throughput << " Mbit/s" << '\n';
-
- return 0;
+
+ return 0;
}
--- a/examples/wireless/simple-two-level-aggregation.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/simple-two-level-aggregation.cc Thu Sep 03 22:16:49 2015 +0200
@@ -102,8 +102,8 @@
wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
//We consider a constant bitrate since HT rate adaptation algorithms are not supported yet in the simulator
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
- "DataMode", StringValue ("OfdmRate65MbpsBW20MHz"),
- "ControlMode", StringValue ("OfdmRate6_5MbpsBW20MHz"));
+ "DataMode", StringValue ("HtMcs7"),
+ "ControlMode", StringValue ("HtMcs0"));
HtWifiMacHelper mac = HtWifiMacHelper::Default ();
Ssid ssid = Ssid ("simple-two-level-aggregation");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/wireless/vht-wifi-network.cc Thu Sep 03 22:16:49 2015 +0200
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2015 SEBASTIEN DERONNE
+ *
+ * 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: Sebastien Deronne <sebastien.deronne@gmail.com>
+ */
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/internet-module.h"
+
+//This is a simple example of an IEEE 802.11ac Wi-Fi network.
+//
+//Network topology:
+//
+// Wifi 192.168.1.0
+//
+// AP
+// * *
+// | |
+// n1 n2
+//
+//Packets in this simulation aren't marked with a QosTag so they are considered
+//belonging to BestEffort Access Class (AC_BE).
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("vht-wifi-network");
+
+int main (int argc, char *argv[])
+{
+ bool udp = true;
+ double simulationTime = 10; //seconds
+ CommandLine cmd;
+ cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
+ cmd.AddValue ("udp", "UDP if set to 1, TCP otherwise", udp);
+ cmd.Parse (argc,argv);
+
+ std::cout << "MCS value" << "\t\t" << "Channel width" << "\t\t" << "short GI" << "\t\t" << "Throughput" << '\n';
+ for (int i = 0; i <= 9; i++) //MCS
+ {
+ for (int j = 20; j <= 160; ) //channel width
+ {
+ if (i == 9 && j == 20)
+ {
+ j *= 2;
+ continue;
+ }
+ for (int k = 0; k < 2; k++) //GI: 0 and 1
+ {
+ uint32_t payloadSize; //1500 byte IP packet
+ if (udp)
+ {
+ payloadSize = 1472; //bytes
+ }
+ else
+ {
+ payloadSize = 1448; //bytes
+ Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
+ }
+
+ NodeContainer wifiStaNode;
+ wifiStaNode.Create (1);
+ NodeContainer wifiApNode;
+ wifiApNode.Create (1);
+
+ YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
+ YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+ phy.SetChannel (channel.Create ());
+
+ // Set guard interval
+ phy.Set ("ShortGuardEnabled", BooleanValue (k));
+
+ WifiHelper wifi = WifiHelper::Default ();
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211ac);
+ VhtWifiMacHelper mac = VhtWifiMacHelper::Default ();
+
+ Ssid ssid = Ssid ("ns380211ac");
+
+ std::stringstream sstmp;
+ std::string strtmp, dataRate;
+ StringValue DataRate;
+
+ sstmp << i;
+ sstmp >> strtmp;
+ dataRate = "VhtMcs" + strtmp;
+ DataRate = StringValue (dataRate);
+
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", DataRate,
+ "ControlMode", DataRate);
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+
+ NetDeviceContainer staDevice;
+ staDevice = wifi.Install (phy, mac, wifiStaNode);
+
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+
+ NetDeviceContainer apDevice;
+ apDevice = wifi.Install (phy, mac, wifiApNode);
+
+ // Set channel width
+ Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", UintegerValue (j));
+
+ // mobility.
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (1.0, 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 (4294967295u));
+ myClient.SetAttribute ("Interval", TimeValue (Time ("0.00001"))); //packets/s
+ 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));
+ }
+
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+ Simulator::Stop (Seconds (simulationTime + 1));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ double throughput = 0;
+ if (udp)
+ {
+ //UDP
+ uint32_t totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
+ throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ else
+ {
+ //TCP
+ uint32_t totalPacketsThrough = DynamicCast<PacketSink> (sinkApp.Get (0))->GetTotalRx ();
+ throughput = totalPacketsThrough * 8 / (simulationTime * 1000000.0); //Mbit/s
+ }
+ std::cout << dataRate << "\t\t\t" << j << " MHz\t\t\t" << k << "\t\t\t" << throughput << " Mbit/s" << std::endl;
+ }
+ j *= 2;
+ }
+ }
+ return 0;
+}
--- a/examples/wireless/wscript Wed Sep 02 16:37:05 2015 -0700
+++ b/examples/wireless/wscript Thu Sep 03 22:16:49 2015 +0200
@@ -49,12 +49,18 @@
obj = bld.create_ns3_program('ofdm-ht-validation', ['core', 'mobility', 'wifi', 'config-store', 'stats'])
obj.source = 'ofdm-ht-validation.cc'
+ obj = bld.create_ns3_program('ofdm-vht-validation', ['core', 'mobility', 'wifi', 'config-store', 'stats'])
+ obj.source = 'ofdm-vht-validation.cc'
+
obj = bld.create_ns3_program('wifi-hidden-terminal', ['internet', 'mobility', 'wifi', 'applications', 'propagation', 'flow-monitor'])
obj.source = 'wifi-hidden-terminal.cc'
obj = bld.create_ns3_program('ht-wifi-network', ['core','internet', 'mobility', 'wifi', 'applications', 'propagation'])
obj.source = 'ht-wifi-network.cc'
+ obj = bld.create_ns3_program('vht-wifi-network', ['core','internet', 'mobility', 'wifi', 'applications', 'propagation'])
+ obj.source = 'vht-wifi-network.cc'
+
obj = bld.create_ns3_program('wifi-timing-attributes', ['core','internet', 'mobility', 'wifi', 'applications', 'propagation'])
obj.source = 'wifi-timing-attributes.cc'
--- a/src/mesh/model/mesh-wifi-interface-mac.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/mesh/model/mesh-wifi-interface-mac.cc Thu Sep 03 22:16:49 2015 +0200
@@ -74,8 +74,8 @@
;
return tid;
}
-MeshWifiInterfaceMac::MeshWifiInterfaceMac () :
- m_standard (WIFI_PHY_STANDARD_80211a)
+MeshWifiInterfaceMac::MeshWifiInterfaceMac ()
+ : m_standard (WIFI_PHY_STANDARD_80211a)
{
NS_LOG_FUNCTION (this);
@@ -265,7 +265,7 @@
}
else
{
- // No tag found; set to best effort
+ // No tag found; set to best effort
ac = AC_BE;
hdr.SetQosTid (0);
}
@@ -319,13 +319,13 @@
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
- rates.AddSupportedRate (mode.GetDataRate ());
+ rates.AddSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth (), m_phy->GetGuardInterval (), 1));
}
// set the basic rates
for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
{
WifiMode mode = m_stationManager->GetBasicMode (j);
- rates.SetBasicRate (mode.GetDataRate ());
+ rates.SetBasicRate (mode.GetDataRate (m_phy->GetChannelWidth (), m_phy->GetGuardInterval (), 1));
}
return rates;
}
@@ -335,7 +335,7 @@
for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
{
WifiMode mode = m_stationManager->GetBasicMode (i);
- if (!rates.IsSupportedRate (mode.GetDataRate ()))
+ if (!rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth (), m_phy->GetGuardInterval (), 1)))
{
return false;
}
@@ -442,10 +442,10 @@
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
- if (rates.IsSupportedRate (mode.GetDataRate ()))
+ if (rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth (), m_phy->GetGuardInterval (), 1)))
{
m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
- if (rates.IsBasicRate (mode.GetDataRate ()))
+ if (rates.IsBasicRate (mode.GetDataRate (m_phy->GetChannelWidth (), m_phy->GetGuardInterval (), 1)))
{
m_stationManager->AddBasicMode (mode);
}
@@ -508,28 +508,32 @@
return m_mpAddress;
}
//Statistics:
-MeshWifiInterfaceMac::Statistics::Statistics () :
- recvBeacons (0), sentFrames (0), sentBytes (0), recvFrames (0), recvBytes (0)
+MeshWifiInterfaceMac::Statistics::Statistics ()
+ : recvBeacons (0),
+ sentFrames (0),
+ sentBytes (0),
+ recvFrames (0),
+ recvBytes (0)
{
}
void
MeshWifiInterfaceMac::Statistics::Print (std::ostream & os) const
{
os << "<Statistics "
- /// \todo txBeacons
- "rxBeacons=\"" << recvBeacons << "\" "
- "txFrames=\"" << sentFrames << "\" "
- "txBytes=\"" << sentBytes << "\" "
- "rxFrames=\"" << recvFrames << "\" "
- "rxBytes=\"" << recvBytes << "\"/>" << std::endl;
+ /// \todo txBeacons
+ "rxBeacons=\"" << recvBeacons << "\" "
+ "txFrames=\"" << sentFrames << "\" "
+ "txBytes=\"" << sentBytes << "\" "
+ "rxFrames=\"" << recvFrames << "\" "
+ "rxBytes=\"" << recvBytes << "\"/>" << std::endl;
}
void
MeshWifiInterfaceMac::Report (std::ostream & os) const
{
os << "<Interface "
- "BeaconInterval=\"" << GetBeaconInterval ().GetSeconds () << "\" "
- "Channel=\"" << GetFrequencyChannel () << "\" "
- "Address = \"" << GetAddress () << "\">" << std::endl;
+ "BeaconInterval=\"" << GetBeaconInterval ().GetSeconds () << "\" "
+ "Channel=\"" << GetFrequencyChannel () << "\" "
+ "Address = \"" << GetAddress () << "\">" << std::endl;
m_stats.Print (os);
os << "</Interface>" << std::endl;
}
--- a/src/network/utils/radiotap-header.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/network/utils/radiotap-header.cc Thu Sep 03 22:16:49 2015 +0200
@@ -42,7 +42,14 @@
m_antennaNoise (0),
m_ampduStatusRef (0),
m_ampduStatusFlags (0),
- m_ampduStatusCRC (0)
+ m_ampduStatusCRC (0),
+ m_vhtPad (0),
+ m_vhtKnown (0),
+ m_vhtFlags (0),
+ m_vhtBandwidth (0),
+ m_vhtCoding (0),
+ m_vhtGroupId (0),
+ m_vhtPartialAid (0)
{
NS_LOG_FUNCTION (this);
}
@@ -238,17 +245,17 @@
//
if (m_present & RADIOTAP_VHT) // bit 21
{
- //not yet implemented
- start.WriteU16 (0);
- start.WriteU8 (0);
- start.WriteU8 (0);
- start.WriteU8 (0);
- start.WriteU8 (0);
- start.WriteU8 (0);
- start.WriteU8 (0);
- start.WriteU8 (0);
- start.WriteU8 (0);
- start.WriteU16 (0);
+ start.WriteU8 (0, m_vhtPad);
+ start.WriteU16 (m_vhtKnown);
+ start.WriteU8 (m_vhtFlags);
+ start.WriteU8 (m_vhtBandwidth);
+ for (uint8_t i = 0; i < 4; i++)
+ {
+ start.WriteU8 (m_vhtMcsNss[i]);
+ }
+ start.WriteU8 (m_vhtCoding);
+ start.WriteU8 (m_vhtGroupId);
+ start.WriteU16 (m_vhtPartialAid);
}
}
@@ -450,18 +457,19 @@
//
if (m_present & RADIOTAP_VHT) // bit 21
{
- //not yet implemented
- start.ReadU16 ();
- start.ReadU8 ();
- start.ReadU8 ();
- start.ReadU8 ();
- start.ReadU8 ();
- start.ReadU8 ();
- start.ReadU8 ();
- start.ReadU8 ();
- start.ReadU8 ();
- start.ReadU16 ();
- bytesRead += 12;
+ m_vhtPad = ((2 - bytesRead % 2) % 2);
+ start.Next (m_vhtPad);
+ m_vhtKnown = start.ReadU16 ();
+ m_vhtFlags = start.ReadU8 ();
+ m_vhtBandwidth = start.ReadU8 ();
+ for (uint8_t i = 0; i < 4; i++)
+ {
+ m_vhtMcsNss[i] = start.ReadU8 ();
+ }
+ m_vhtCoding = start.ReadU8 ();
+ m_vhtGroupId = start.ReadU8 ();
+ m_vhtPartialAid = start.ReadU16 ();
+ bytesRead += (12 + m_vhtPad);
}
NS_ASSERT_MSG (m_length == bytesRead, "RadiotapHeader::Deserialize(): expected and actual lengths inconsistent");
@@ -482,7 +490,17 @@
<< " mcsKnown=" << m_mcsKnown
<< " mcsFlags=" << m_mcsFlags
<< " mcsRate=" << m_mcsRate
- << " ampduStatusFlags=" << (int16_t) m_ampduStatusFlags;
+ << " ampduStatusFlags=" << (int16_t) m_ampduStatusFlags
+ << " vhtKnown=" << m_vhtKnown
+ << " vhtFlags=" << m_vhtFlags
+ << " vhtBandwidth=" << m_vhtBandwidth
+ << " vhtMcsNss for user 1=" << m_vhtMcsNss[0]
+ << " vhtMcsNss for user 2=" << m_vhtMcsNss[1]
+ << " vhtMcsNss for user 3=" << m_vhtMcsNss[2]
+ << " vhtMcsNss for user 4=" << m_vhtMcsNss[3]
+ << " vhtCoding=" << m_vhtCoding
+ << " vhtGroupId=" << m_vhtGroupId
+ << " vhtPartialAid=" << m_vhtPartialAid;
}
void
@@ -716,4 +734,98 @@
return m_ampduStatusFlags;
}
+void
+RadiotapHeader::SetVhtFields (uint16_t known, uint8_t flags, uint8_t bandwidth, uint8_t mcs_nss[4], uint8_t coding, uint8_t group_id, uint16_t partial_aid)
+{
+ NS_LOG_FUNCTION (this << known << flags << mcs_nss[0] << mcs_nss[1] << mcs_nss[2] << mcs_nss[3] << coding << group_id << partial_aid);
+ m_vhtKnown = known;
+ m_vhtFlags = flags;
+ m_vhtBandwidth = bandwidth;
+ for (uint8_t i = 0; i < 4; i++)
+ {
+ m_vhtMcsNss[i] = mcs_nss[i];
+ }
+ m_vhtCoding = coding;
+ m_vhtGroupId = group_id;
+ m_vhtPartialAid = partial_aid;
+ if (!(m_present & RADIOTAP_VHT))
+ {
+ m_vhtPad = ((2 - m_length % 2) % 2);
+ m_present |= RADIOTAP_VHT;
+ m_length += (12 + m_vhtPad);
+ }
+
+ NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
+}
+
+uint16_t
+RadiotapHeader::GetVhtKnown () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtKnown;
+}
+
+uint8_t
+RadiotapHeader::GetVhtFlags () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtFlags;
+}
+
+uint8_t
+RadiotapHeader::GetVhtBandwidth () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtBandwidth;
+}
+
+uint8_t
+RadiotapHeader::GetVhtMcsNssUser1 () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtMcsNss[0];
+}
+
+uint8_t
+RadiotapHeader::GetVhtMcsNssUser2 () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtMcsNss[1];
+}
+
+uint8_t
+RadiotapHeader::GetVhtMcsNssUser3 () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtMcsNss[2];
+}
+
+uint8_t
+RadiotapHeader::GetVhtMcsNssUser4 () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtMcsNss[3];
+}
+
+uint8_t
+RadiotapHeader::GetVhtCoding () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtCoding;
+}
+
+uint8_t
+RadiotapHeader::GetVhtGroupId () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtGroupId;
+}
+
+uint8_t
+RadiotapHeader::GetVhtPartialAid () const
+{
+ NS_LOG_FUNCTION (this);
+ return m_vhtPartialAid;
+}
+
} // namespace ns3
--- a/src/network/utils/radiotap-header.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/network/utils/radiotap-header.h Thu Sep 03 22:16:49 2015 +0200
@@ -306,6 +306,108 @@
*/
uint16_t GetAmpduStatusFlags (void) const;
+ enum
+ {
+ VHT_KNOWN_NONE = 0x0000, /**< No flags set */
+ VHT_KNOWN_STBC = 0x0001, /**< Space-time block coding (1 if all spatial streams of all users have STBC, 0 otherwise). */
+ VHT_KNOWN_TXOP_PS_NOT_ALLOWED = 0x0002, /**< TXOP_PS_NOT_ALLOWED known */
+ VHT_KNOWN_GUARD_INTERVAL = 0x0004, /**< Guard interval */
+ VHT_KNOWN_SHORT_GI_NSYM_DISAMBIGUATION = 0x0008, /**< Short GI NSYM disambiguation known */
+ VHT_KNOWN_LDPC_EXTRA_OFDM_SYMBOL = 0x0010, /**< LDPC extra OFDM symbol known */
+ VHT_KNOWN_BEAMFORMED = 0x0020, /**< Beamformed known/applicable (this flag should be set to zero for MU PPDUs). */
+ VHT_KNOWN_BANDWIDTH = 0x0040, /**< Bandwidth known */
+ VHT_KNOWN_GROUP_ID = 0x0080, /**< Group ID known */
+ VHT_KNOWN_PARTIAL_AID = 0x0100, /**< Partial AID known/applicable */
+ };
+
+ enum
+ {
+ VHT_FLAGS_NONE = 0x00, /**< No flags set */
+ VHT_FLAGS_STBC = 0x01, /**< Set if all spatial streams of all users have space-time block coding */
+ VHT_FLAGS_TXOP_PS_NOT_ALLOWED = 0x02, /**< Set if STAs may not doze during TXOP (valid only for AP transmitters). */
+ VHT_FLAGS_GUARD_INTERVAL = 0x04, /**< Short guard interval */
+ VHT_FLAGS_SHORT_GI_NSYM_DISAMBIGUATION = 0x08, /**< Set if NSYM mod 10 = 9 (valid only if short GI is used).*/
+ VHT_FLAGS__LDPC_EXTRA_OFDM_SYMBOL = 0x10, /**< Set if one or more users are using LDPC and the encoding process resulted in extra OFDM symbol(s) */
+ VHT_FLAGS_BEAMFORMED = 0x20, /**< Set if beamforming is used (valid for SU PPDUs only). */
+ };
+
+ /**
+ * @brief Set the VHT fields
+ *
+ * @param known The kwown flags.
+ * @param flags The flags to set.
+ * @param bandwidth The bandwidth value.
+ * @param mcs_nss The mcs_nss value.
+ * @param coding The coding value.
+ * @param group_id The group_id value.
+ * @param partial_aid The partial_aid value.
+ */
+ void SetVhtFields (uint16_t known, uint8_t flags,
+ uint8_t bandwidth, uint8_t mcs_nss [4],
+ uint8_t coding, uint8_t group_id,
+ uint16_t partial_aid);
+
+ /**
+ * @brief Get the VHT known bitmap.
+ *
+ * @returns The MCS known bitmap.
+ */
+ uint16_t GetVhtKnown (void) const;
+ /**
+ * @brief Get the VHT flags.
+ *
+ * @returns The VHT flags.
+ */
+ uint8_t GetVhtFlags (void) const;
+ /**
+ * @brief Get the VHT bandwidth field value.
+ *
+ * @returns The VHT bandwidth field value.
+ */
+ uint8_t GetVhtBandwidth (void) const;
+ /**
+ * @brief Get the VHT mcs_nss field value for user 1.
+ *
+ * @returns The VHT mcs_nss field value for user 1.
+ */
+ uint8_t GetVhtMcsNssUser1 () const;
+ /**
+ * @brief Get the VHT mcs_nss field value for user 2.
+ *
+ * @returns The VHT mcs_nss field value for user 2.
+ */
+ uint8_t GetVhtMcsNssUser2 () const;
+ /**
+ * @brief Get the VHT mcs_nss field value for user 3.
+ *
+ * @returns The VHT mcs_nss field value for user 3.
+ */
+ uint8_t GetVhtMcsNssUser3 () const;
+ /**
+ * @brief Get the VHT mcs_nss field value for user 4.
+ *
+ * @returns The VHT mcs_nss field value for user 4.
+ */
+ uint8_t GetVhtMcsNssUser4 () const;
+ /**
+ * @brief Get the VHT coding field value.
+ *
+ * @returns The VHT coding field value.
+ */
+ uint8_t GetVhtCoding (void) const;
+ /**
+ * @brief Get the VHT group_id field value.
+ *
+ * @returns The VHT group_id field value.
+ */
+ uint8_t GetVhtGroupId (void) const;
+ /**
+ * @brief Get the VHT partial_aid field value.
+ *
+ * @returns The VHT partial_aid field value.
+ */
+ uint8_t GetVhtPartialAid (void) const;
+
private:
enum
@@ -351,6 +453,15 @@
uint32_t m_ampduStatusRef; //!< A-MPDU Status Flags, reference number.
uint16_t m_ampduStatusFlags; //!< A-MPDU Status Flags, information about the received A-MPDU.
uint8_t m_ampduStatusCRC; //!< A-MPDU Status Flags, delimiter CRC value.
+
+ uint8_t m_vhtPad; //!< VHT padding.
+ uint16_t m_vhtKnown; //!< VHT known field.
+ uint8_t m_vhtFlags; //!< VHT flags field.
+ uint8_t m_vhtBandwidth; //!< VHT bandwidth field.
+ uint8_t m_vhtMcsNss[4]; //!< VHT mcs_nss field.
+ uint8_t m_vhtCoding; //!< VHT coding field.
+ uint8_t m_vhtGroupId; //!< VHT group_id field.
+ uint16_t m_vhtPartialAid; //!< VHT partial_aid field.
};
} // namespace ns3
--- a/src/wave/helper/wave-helper.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wave/helper/wave-helper.cc Thu Sep 03 22:16:49 2015 +0200
@@ -168,7 +168,7 @@
mcsRate = rate - 128;
mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH;
- if (txVector.GetMode ().GetBandwidth () == 40000000)
+ if (txVector.GetChannelWidth () == 40000000)
{
mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40;
}
@@ -211,19 +211,65 @@
uint16_t ampduStatusFlags = RadiotapHeader::A_MPDU_STATUS_NONE;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN;
- if (aMpdu.packetType == 2)
- {
- ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
- }
/* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */
AmpduSubframeHeader hdr;
uint32_t extractedLength;
p->RemoveHeader (hdr);
extractedLength = hdr.GetLength ();
p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength));
+ if (aMpdu.packetType == 2 || (hdr.GetEof () == true && hdr.GetLength () > 0))
+ {
+ ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
+ }
header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatusFlags, hdr.GetCrc ());
}
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ uint16_t vhtKnown = RadiotapHeader::VHT_KNOWN_NONE;
+ uint8_t vhtFlags = RadiotapHeader::VHT_FLAGS_NONE;
+ uint8_t vhtBandwidth = 0;
+ uint8_t vhtMcsNss[4] = {0,0,0,0};
+ uint8_t vhtCoding = 0;
+ uint8_t vhtGroupId = 0;
+ uint16_t vhtPartialAid = 0;
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_STBC;
+ if (txVector.IsStbc ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_STBC;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_GUARD_INTERVAL;
+ if (txVector.IsShortGuardInterval ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_GUARD_INTERVAL;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BEAMFORMED; //Beamforming is currently not supported
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BANDWIDTH;
+ //not all bandwidth values are currently supported
+ if (txVector.GetChannelWidth () == 40000000)
+ {
+ vhtBandwidth = 1;
+ }
+ else if (txVector.GetChannelWidth () == 80000000)
+ {
+ vhtBandwidth = 4;
+ }
+ else if (txVector.GetChannelWidth () == 160000000)
+ {
+ vhtBandwidth = 11;
+ }
+
+ //only SU PPDUs are currently supported
+ vhtMcsNss[0] |= (txVector.GetNss () & 0x0f);
+ vhtMcsNss[0] |= (((rate - 128) << 4) & 0xf0);
+
+ header.SetVhtFields (vhtKnown, vhtFlags, vhtBandwidth, vhtMcsNss, vhtCoding, vhtGroupId, vhtPartialAid);
+ }
+
p->AddHeader (header);
file->Write (Simulator::Now (), p);
return;
@@ -319,7 +365,7 @@
mcsRate = rate - 128;
mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH;
- if (txVector.GetMode ().GetBandwidth () == 40000000)
+ if (txVector.GetChannelWidth () == 40000000)
{
mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40;
}
@@ -362,19 +408,65 @@
uint16_t ampduStatusFlags = 0;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN;
- if (aMpdu.packetType == 2)
- {
- ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
- }
/* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */
AmpduSubframeHeader hdr;
uint32_t extractedLength;
p->RemoveHeader (hdr);
extractedLength = hdr.GetLength ();
p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength));
+ if (aMpdu.packetType == 2 || (hdr.GetEof () == true && hdr.GetLength () > 0))
+ {
+ ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
+ }
header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatusFlags, hdr.GetCrc ());
}
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ uint16_t vhtKnown = RadiotapHeader::VHT_KNOWN_NONE;
+ uint8_t vhtFlags = RadiotapHeader::VHT_FLAGS_NONE;
+ uint8_t vhtBandwidth = 0;
+ uint8_t vhtMcsNss[4] = {0,0,0,0};
+ uint8_t vhtCoding = 0;
+ uint8_t vhtGroupId = 0;
+ uint16_t vhtPartialAid = 0;
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_STBC;
+ if (txVector.IsStbc ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_STBC;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_GUARD_INTERVAL;
+ if (txVector.IsShortGuardInterval ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_GUARD_INTERVAL;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BEAMFORMED; //Beamforming is currently not supported
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BANDWIDTH;
+ //not all bandwidth values are currently supported
+ if (txVector.GetChannelWidth () == 40000000)
+ {
+ vhtBandwidth = 1;
+ }
+ else if (txVector.GetChannelWidth () == 80000000)
+ {
+ vhtBandwidth = 4;
+ }
+ else if (txVector.GetChannelWidth () == 160000000)
+ {
+ vhtBandwidth = 11;
+ }
+
+ //only SU PPDUs are currently supported
+ vhtMcsNss[0] |= (txVector.GetNss () & 0x0f);
+ vhtMcsNss[0] |= (((rate - 128) << 4) & 0xf0);
+
+ header.SetVhtFields (vhtKnown, vhtFlags, vhtBandwidth, vhtMcsNss, vhtCoding, vhtGroupId, vhtPartialAid);
+ }
+
p->AddHeader (header);
file->Write (Simulator::Now (), p);
return;
--- a/src/wave/model/wave-mac-low.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wave/model/wave-mac-low.cc Thu Sep 03 22:16:49 2015 +0200
@@ -84,7 +84,7 @@
WifiTxVector txAdapter;
// the DataRate set by higher layer is the minimum data rate
// which is the lower bound for the actual data rate.
- if (txHigher.GetMode ().GetDataRate () > txMac.GetMode ().GetDataRate ())
+ if (txHigher.GetMode ().GetDataRate (txHigher.GetChannelWidth (), txHigher.IsShortGuardInterval (), 1) > txMac.GetMode ().GetDataRate (txMac.GetChannelWidth (), txMac.IsShortGuardInterval (), 1))
{
txAdapter.SetMode (txHigher.GetMode ());
}
--- a/src/wifi/doc/source/wifi-user.rst Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/doc/source/wifi-user.rst Thu Sep 03 22:16:49 2015 +0200
@@ -42,9 +42,9 @@
configuration of WifiPhy is the error rate model, which is the one that actually
calculates the probability of successfully decoding the frame based on the signal.
* Configure WifiMac: this step is more on related to the architecture and device level.
- The users configure the wifi architecture (i.e. ad-hoc or ap-sta) and whether QoS (802.11e) and/or HT (802.11n) features are supported or not.
+ The users configure the wifi architecture (i.e. ad-hoc or ap-sta) and whether QoS (802.11e), HT (802.11n) and/or VHT (802.11ac) features are supported or not.
* Create WifiDevice: at this step, users configure the desired wifi standard
- (e.g. **802.11b**, **802.11g**, **802.11a** or **802.11n**) and rate control algorithm
+ (e.g. **802.11b**, **802.11g**, **802.11a**, **802.11n** or **802.11ac**) and rate control algorithm
* Configure mobility: finally, mobility model is (usually) required before WifiNetDevice
can be used.
@@ -113,22 +113,46 @@
prepared the YansWifiPhyHelper by telling it which channel it is connected to.
The Phy objects are created in the next step.
-802.11n PHY layer can use either 20 or 40 MHz channel width, and either long (800 ns) or short (400 ns) OFDM guard intervals. To configure those parameters, the following lines of code could be used (in this example, it configures a 40 MHz channel width with a short guard interval)::
+802.11n/ac PHY layer can use either either long (800 ns) or short (400 ns) OFDM guard intervals. To configure this parameter, the following line of code could be used (in this example, it enables the support of a short guard interval)::
- wifiPhyHelper.Set (« ChannelBonding,BooleanValue(true));
- wifiPhyHelper.Set ("ShortGuardEnabled",BooleanValue(true));
+ wifiPhyHelper.Set ("ShortGuardEnabled", BooleanValue(true));
Furthermore, 802.11n provides an optional mode (GreenField mode) to reduce preamble durations and which is only compatible with 802.11n devices. This mode is enabled as follows::
wifiPhyHelper.Set ("GreenfieldEnabled",BooleanValue(true));
+802.11n PHY layer can support both 20 (default) or 40 MHz channel width, and 802.11ac PHY layer can use either 20, 40, 80 (default) or 160 MHz channel width. Since the channel width value is overwritten by ``WifiHelper::SetStandard``, this should be done post-install using ``Config::Set``::
+
+ WifiHelper wifi = WifiHelper::Default ();
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211ac);
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue("VHtMcs9"), "ControlMode", StringValue("VhtMcs0"));
+ VhtWifiMacHelper mac = VhtWifiMacHelper::Default ();
+
+ //Install PHY and MAC
+ Ssid ssid = Ssid ("ns3-wifi");
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
+
+ NetDeviceContainer staDevice;
+ staDevice = wifi.Install (phy, mac, wifiStaNode);
+
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
+
+ NetDeviceContainer apDevice;
+ apDevice = wifi.Install (phy, mac, wifiApNode);
+
+ //Once install is done, we overwrite the channel width value
+ Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/ChannelWidth", UintegerValue (160));
+
WifiMacHelper
=============
The next step is to configure the MAC model.
We use WifiMacHelper to accomplish this.
WifiMacHelper takes care of both the MAC low model and MAC high model.
-A user must decide if 802.11/WMM-style QoS and/or 802.11n-style High throughput (HT) support is required.
+A user must decide if 802.11/WMM-style QoS and/or 802.11n-style High throughput (HT) and/or 802.11ac-style Very High throughput (VHT) support is required.
NqosWifiMacHelper and QosWifiMacHelper
++++++++++++++++++++++++++++++++++++++
@@ -138,7 +162,7 @@
configure MAC parameters like type of MAC.
The former, ``ns3::NqosWifiMacHelper``, supports creation of MAC
-instances that do not have 802.11e/WMM-style QoS nor 802.11n-style High throughput (HT) support enabled.
+instances that do not have 802.11e/WMM-style QoS nor 802.11n-style High throughput (HT) nor 802.11ac-style Very High throughput (VHT) support enabled.
For example the following user code configures a non-QoS and non-HT MAC that
will be a non-AP STA in an infrastructure network where the AP has
@@ -203,6 +227,13 @@
This object can be also used to set in the same way as ``ns3::QosWifiMacHelper``.
+VhtWifiMacHelper
++++++++++++++++
+
+The ``ns3::VhtWifiMacHelper`` configures an
+object factory to create instances of a ``ns3::WifiMac``. It is used to
+supports creation of MAC instances that have 802.11ac-style Very High throughput (VHT) and QoS support enabled. This object is similar to ``HtWifiMacHelper``.
+
WifiHelper
==========
@@ -229,7 +260,7 @@
WifiHelper wifi = WifiHelper::Default ();
wifi.SetStandard (WIFI_PHY_STANDARD_80211n_2_4GHZ);
- wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue("OfdmRate65MbpsBW20MHz"), "ControlMode", StringValue("OfdmRate6_5MbpsBW20MHz"));
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue("HtMcs7"), "ControlMode", StringValue("HtMcs0"));
HtWifiMacHelper mac = HtWifiMacHelper::Default ();
//Install PHY and MAC
@@ -393,6 +424,5 @@
* 802.11g does not support 9 microseconds slot
* PHY_RXSTART is not supported
* 802.11e TXOP is not supported
-* 802.11n MIMO is not supported
-* hybrid aggregation is not supported
-
+* 802.11n/ac MIMO is not supported
+* 802.11n/ac beamforming is not supported
--- a/src/wifi/examples/test-interference-helper.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/examples/test-interference-helper.cc Thu Sep 03 22:16:49 2015 +0200
@@ -236,6 +236,10 @@
{
input.standard = WIFI_PHY_STANDARD_80211n_5GHZ;
}
+ else if (str_standard == "WIFI_PHY_STANDARD_80211ac")
+ {
+ input.standard = WIFI_PHY_STANDARD_80211ac;
+ }
if (str_preamble == "WIFI_PREAMBLE_LONG" && (input.standard == WIFI_PHY_STANDARD_80211a || input.standard == WIFI_PHY_STANDARD_80211b || input.standard == WIFI_PHY_STANDARD_80211g))
{
@@ -253,6 +257,10 @@
{
input.preamble = WIFI_PREAMBLE_HT_GF;
}
+ else if (str_preamble == "WIFI_PREAMBLE_VHT" && input.standard == WIFI_PHY_STANDARD_80211ac)
+ {
+ input.preamble = WIFI_PREAMBLE_VHT;
+ }
else
{
std::cout << "Preamble does not exist or is not compatible with the selected standard!" << std::endl;
--- a/src/wifi/helper/ht-wifi-mac-helper.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/helper/ht-wifi-mac-helper.cc Thu Sep 03 22:16:49 2015 +0200
@@ -40,9 +40,6 @@
{
HtWifiMacHelper helper;
- //We're making Ht-enabled Wi-Fi MACs here, so we set the necessary
- //attribute. I've carefully positioned this here so that someone
- //who knows what they're doing can override with explicit attributes.
helper.SetType ("ns3::StaWifiMac",
"QosSupported", BooleanValue (true),
"HtSupported", BooleanValue (true));
--- a/src/wifi/helper/ht-wifi-mac-helper.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/helper/ht-wifi-mac-helper.h Thu Sep 03 22:16:49 2015 +0200
@@ -38,7 +38,7 @@
{
public:
/**
- * Create a QosWifiMacHelper that is used to make life easier when working
+ * Create a HtWifiMacHelper that is used to make life easier when working
* with Wifi devices using a QOS MAC layer.
*/
HtWifiMacHelper ();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/helper/vht-wifi-mac-helper.cc Thu Sep 03 22:16:49 2015 +0200
@@ -0,0 +1,57 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 SEBASTIEN DERONNE
+ *
+ * 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 <sebastien.deronne@gmail.com>
+ */
+
+#include "vht-wifi-mac-helper.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/edca-txop-n.h"
+#include "ns3/pointer.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+VhtWifiMacHelper::VhtWifiMacHelper ()
+{
+}
+
+VhtWifiMacHelper::~VhtWifiMacHelper ()
+{
+}
+
+VhtWifiMacHelper
+VhtWifiMacHelper::Default (void)
+{
+ VhtWifiMacHelper helper;
+
+ helper.SetType ("ns3::StaWifiMac",
+ "QosSupported", BooleanValue (true),
+ "HtSupported", BooleanValue (true), //by default, it also supports HT features
+ "VhtSupported", BooleanValue (true));
+
+ //MPDU aggregation is always supported
+ helper.SetMpduAggregatorForAc (AC_VO, "ns3::MpduStandardAggregator");
+ helper.SetMpduAggregatorForAc (AC_VI, "ns3::MpduStandardAggregator");
+ helper.SetMpduAggregatorForAc (AC_BE, "ns3::MpduStandardAggregator");
+ helper.SetMpduAggregatorForAc (AC_BK, "ns3::MpduStandardAggregator");
+
+ return helper;
+}
+
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/helper/vht-wifi-mac-helper.h Thu Sep 03 22:16:49 2015 +0200
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 SEBASTIEN DERONNE
+ *
+ * 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 <sebastien.deronne@gmail.com>
+ */
+
+#ifndef VHT_WIFI_MAC_HELPER_H
+#define VHT_WIFI_MAC_HELPER_H
+
+#include "wifi-helper.h"
+#include "ns3/qos-utils.h"
+#include "qos-wifi-mac-helper.h"
+#include <map>
+
+namespace ns3 {
+
+/**
+ * \brief create VHT-enabled MAC layers for a ns3::WifiNetDevice.
+ *
+ * This class can create MACs of type ns3::ApWifiMac, ns3::StaWifiMac,
+ * and, ns3::AdhocWifiMac, with QosSupported, HTSupported and VHTSupported attributes set to True.
+ */
+class VhtWifiMacHelper : public QosWifiMacHelper
+{
+public:
+ /**
+ * Create a VhtWifiMacHelper that is used to make life easier when working
+ * with Wifi devices using a QOS MAC layer.
+ */
+ VhtWifiMacHelper ();
+
+ /**
+ * \internal
+ * Destroy a VhtWifiMacHelper
+ */
+ virtual ~VhtWifiMacHelper ();
+
+ /**
+ * Create a mac helper in a default working state.
+ */
+ static VhtWifiMacHelper Default (void);
+
+};
+
+} //namespace ns3
+
+#endif /* VHT_WIFI_MAC_HELPER_H */
--- a/src/wifi/helper/yans-wifi-helper.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/helper/yans-wifi-helper.cc Thu Sep 03 22:16:49 2015 +0200
@@ -330,7 +330,7 @@
mcsRate = rate - 128;
mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH;
- if (txVector.GetMode ().GetBandwidth () == 40000000)
+ if (txVector.GetChannelWidth () == 40000000)
{
mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40;
}
@@ -373,19 +373,65 @@
uint16_t ampduStatusFlags = RadiotapHeader::A_MPDU_STATUS_NONE;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN;
- if (aMpdu.packetType == 2)
- {
- ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
- }
/* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */
AmpduSubframeHeader hdr;
uint32_t extractedLength;
p->RemoveHeader (hdr);
extractedLength = hdr.GetLength ();
p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength));
+ if (aMpdu.packetType == 2 || (hdr.GetEof () == true && hdr.GetLength () > 0))
+ {
+ ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
+ }
header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatusFlags, hdr.GetCrc ());
}
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ uint16_t vhtKnown = RadiotapHeader::VHT_KNOWN_NONE;
+ uint8_t vhtFlags = RadiotapHeader::VHT_FLAGS_NONE;
+ uint8_t vhtBandwidth = 0;
+ uint8_t vhtMcsNss[4] = {0,0,0,0};
+ uint8_t vhtCoding = 0;
+ uint8_t vhtGroupId = 0;
+ uint16_t vhtPartialAid = 0;
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_STBC;
+ if (txVector.IsStbc ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_STBC;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_GUARD_INTERVAL;
+ if (txVector.IsShortGuardInterval ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_GUARD_INTERVAL;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BEAMFORMED; //Beamforming is currently not supported
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BANDWIDTH;
+ //not all bandwidth values are currently supported
+ if (txVector.GetChannelWidth () == 40000000)
+ {
+ vhtBandwidth = 1;
+ }
+ else if (txVector.GetChannelWidth () == 80000000)
+ {
+ vhtBandwidth = 4;
+ }
+ else if (txVector.GetChannelWidth () == 160000000)
+ {
+ vhtBandwidth = 11;
+ }
+
+ //only SU PPDUs are currently supported
+ vhtMcsNss[0] |= (txVector.GetNss () & 0x0f);
+ vhtMcsNss[0] |= (((rate - 128) << 4) & 0xf0);
+
+ header.SetVhtFields (vhtKnown, vhtFlags, vhtBandwidth, vhtMcsNss, vhtCoding, vhtGroupId, vhtPartialAid);
+ }
+
p->AddHeader (header);
file->Write (Simulator::Now (), p);
return;
@@ -481,7 +527,7 @@
mcsRate = rate - 128;
mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH;
- if (txVector.GetMode ().GetBandwidth () == 40000000)
+ if (txVector.GetChannelWidth () == 40000000)
{
mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40;
}
@@ -524,19 +570,65 @@
uint16_t ampduStatusFlags = 0;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN;
ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN;
- if (aMpdu.packetType == 2)
- {
- ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
- }
/* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */
AmpduSubframeHeader hdr;
uint32_t extractedLength;
p->RemoveHeader (hdr);
extractedLength = hdr.GetLength ();
p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength));
+ if (aMpdu.packetType == 2 || (hdr.GetEof () == true && hdr.GetLength () > 0))
+ {
+ ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST;
+ }
header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatusFlags, hdr.GetCrc ());
}
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ uint16_t vhtKnown = RadiotapHeader::VHT_KNOWN_NONE;
+ uint8_t vhtFlags = RadiotapHeader::VHT_FLAGS_NONE;
+ uint8_t vhtBandwidth = 0;
+ uint8_t vhtMcsNss[4] = {0,0,0,0};
+ uint8_t vhtCoding = 0;
+ uint8_t vhtGroupId = 0;
+ uint16_t vhtPartialAid = 0;
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_STBC;
+ if (txVector.IsStbc ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_STBC;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_GUARD_INTERVAL;
+ if (txVector.IsShortGuardInterval ())
+ {
+ vhtFlags |= RadiotapHeader::VHT_FLAGS_GUARD_INTERVAL;
+ }
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BEAMFORMED; //Beamforming is currently not supported
+
+ vhtKnown |= RadiotapHeader::VHT_KNOWN_BANDWIDTH;
+ //not all bandwidth values are currently supported
+ if (txVector.GetChannelWidth () == 40000000)
+ {
+ vhtBandwidth = 1;
+ }
+ else if (txVector.GetChannelWidth () == 80000000)
+ {
+ vhtBandwidth = 4;
+ }
+ else if (txVector.GetChannelWidth () == 160000000)
+ {
+ vhtBandwidth = 11;
+ }
+
+ //only SU PPDUs are currently supported
+ vhtMcsNss[0] |= (txVector.GetNss () & 0x0f);
+ vhtMcsNss[0] |= (((rate - 128) << 4) & 0xf0);
+
+ header.SetVhtFields (vhtKnown, vhtFlags, vhtBandwidth, vhtMcsNss, vhtCoding, vhtGroupId, vhtPartialAid);
+ }
+
p->AddHeader (header);
file->Write (Simulator::Now (), p);
return;
--- a/src/wifi/model/aarf-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/aarf-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -232,7 +232,13 @@
{
NS_LOG_FUNCTION (this << st << size);
AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
@@ -242,7 +248,13 @@
/// \todo we could/should implement the Aarf algorithm for
/// RTS only by picking a single rate within the BasicRateSet.
AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/aarfcd-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/aarfcd-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -304,8 +304,15 @@
{
NS_LOG_FUNCTION (this << st << size);
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
+
WifiTxVector
AarfcdWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
{
@@ -313,7 +320,13 @@
/// \todo we could/should implement the Aarf algorithm for
/// RTS only by picking a single rate within the BasicRateSet.
AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/ampdu-subframe-header.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/ampdu-subframe-header.cc Thu Sep 03 22:16:49 2015 +0200
@@ -43,7 +43,8 @@
}
AmpduSubframeHeader::AmpduSubframeHeader ()
- : m_length (0)
+ : m_length (0),
+ m_eof (0)
{
}
@@ -60,7 +61,7 @@
void
AmpduSubframeHeader::Serialize (Buffer::Iterator i) const
{
- i.WriteHtolsbU16 (m_length);
+ i.WriteHtolsbU16 ((m_eof << 15) | m_length);
i.WriteU8 (m_crc);
i.WriteU8 (m_sig);
}
@@ -69,7 +70,9 @@
AmpduSubframeHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
- m_length = i.ReadLsbtohU16 ();
+ uint16_t field = i.ReadLsbtohU16 ();
+ m_eof = (field & 0x8000) >> 15;
+ m_length = (field & 0x3fff);
m_crc = i.ReadU8 ();
m_sig = i.ReadU8 ();
return i.GetDistanceFrom (start);
@@ -78,7 +81,7 @@
void
AmpduSubframeHeader::Print (std::ostream &os) const
{
- os << "length = " << m_length << ", CRC = " << m_crc << ", Signature = " << m_sig;
+ os << "EOF = " << m_eof << "length = " << m_length << ", CRC = " << m_crc << ", Signature = " << m_sig;
}
void
@@ -99,6 +102,12 @@
m_length = length;
}
+void
+AmpduSubframeHeader::SetEof (bool eof)
+{
+ m_eof = eof;
+}
+
uint8_t
AmpduSubframeHeader::GetCrc (void) const
{
@@ -117,4 +126,10 @@
return m_length;
}
+bool
+AmpduSubframeHeader::GetEof (void) const
+{
+ return m_eof;
+}
+
} //namespace ns3
--- a/src/wifi/model/ampdu-subframe-header.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/ampdu-subframe-header.h Thu Sep 03 22:16:49 2015 +0200
@@ -63,6 +63,12 @@
*/
void SetLength (uint16_t length);
/**
+ * Set the EOF field.
+ *
+ * \param eof
+ */
+ void SetEof (bool eof);
+ /**
* Return the CRC field.
*
* \return the CRC field
@@ -80,11 +86,18 @@
* \return the length field
*/
uint16_t GetLength (void) const;
+ /**
+ * Return the EOF field.
+ *
+ * \return the EOF field
+ */
+ bool GetEof (void) const;
-private:
+protected:
uint8_t m_crc; //!< CRC field
uint8_t m_sig; //!< SIG field
uint16_t m_length; //!< length field
+ bool m_eof; //!< EOF field
};
} //namespace ns3
--- a/src/wifi/model/amrr-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/amrr-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -335,8 +335,13 @@
rateIndex = station->m_txrate;
}
}
-
- return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
@@ -344,9 +349,15 @@
{
NS_LOG_FUNCTION (this << st);
AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st;
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
UpdateMode (station);
/// \todo can we implement something smarter ?
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/ap-wifi-mac.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/ap-wifi-mac.cc Thu Sep 03 22:16:49 2015 +0200
@@ -245,7 +245,7 @@
hdr.SetTypeData ();
}
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
hdr.SetNoOrder ();
}
@@ -303,7 +303,7 @@
//which only includes 127 for HT now. The standard says that the BSSMembershipSelectorSet
//must have its MSB set to 1 (must be treated as a Basic Rate)
//Also the standard mentioned that at leat 1 element should be included in the SupportedRates the rest can be in the ExtendedSupportedRates
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors (); i++)
{
@@ -315,12 +315,16 @@
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
- rates.AddSupportedRate (mode.GetDataRate ());
+ uint32_t channelWidth = m_phy->GetChannelWidth ();
+ if (channelWidth > 20)
+ {
+ channelWidth = 20;
+ }
+ rates.AddSupportedRate (mode.GetDataRate (channelWidth, false, 1));
//Add rates that are part of the BSSBasicRateSet (manufacturer dependent!)
//here we choose to add the mandatory rates to the BSSBasicRateSet,
- //exept for 802.11b where we assume that only the two lowest mandatory rates are part of the BSSBasicRateSet
- if (mode.IsMandatory ()
- && ((mode.GetModulationClass () != WIFI_MOD_CLASS_DSSS) || mode == WifiPhy::GetDsssRate1Mbps () || mode == WifiPhy::GetDsssRate2Mbps ()))
+ //exept for 802.11b where we assume that only the non HR-DSSS rates are part of the BSSBasicRateSet
+ if (mode.IsMandatory () && (mode.GetModulationClass () != WIFI_MOD_CLASS_HR_DSSS))
{
m_stationManager->AddBasicMode (mode);
}
@@ -329,7 +333,12 @@
for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
{
WifiMode mode = m_stationManager->GetBasicMode (j);
- rates.SetBasicRate (mode.GetDataRate ());
+ uint32_t channelWidth = m_phy->GetChannelWidth ();
+ if (channelWidth > 20)
+ {
+ channelWidth = 20;
+ }
+ rates.SetBasicRate (mode.GetDataRate (channelWidth, false, 1));
}
return rates;
@@ -340,26 +349,65 @@
{
HtCapabilities capabilities;
capabilities.SetHtSupported (1);
- capabilities.SetLdpc (m_phy->GetLdpc ());
- capabilities.SetSupportedChannelWidth (m_phy->GetChannelBonding ());
- capabilities.SetShortGuardInterval20 (m_phy->GetGuardInterval ());
- capabilities.SetShortGuardInterval40 (m_phy->GetChannelBonding () && m_phy->GetGuardInterval ());
- capabilities.SetGreenfield (m_phy->GetGreenfield ());
- capabilities.SetMaxAmsduLength (1); //hardcoded for now (TBD)
- capabilities.SetLSigProtectionSupport (!m_phy->GetGreenfield ());
- capabilities.SetMaxAmpduLength (3); //hardcoded for now (TBD)
- uint64_t maxSupportedRate = 0; //in bit/s
- for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
+ if (m_htSupported)
{
- capabilities.SetRxMcsBitmask (m_phy->GetMcs (i));
- if (((m_phy->McsToWifiMode (i)).GetDataRate ()) > maxSupportedRate)
+ capabilities.SetLdpc (m_phy->GetLdpc ());
+ capabilities.SetSupportedChannelWidth (m_phy->GetChannelWidth () == 40);
+ capabilities.SetShortGuardInterval20 (m_phy->GetGuardInterval ());
+ capabilities.SetShortGuardInterval40 (m_phy->GetChannelWidth () == 40 && m_phy->GetGuardInterval ());
+ capabilities.SetGreenfield (m_phy->GetGreenfield ());
+ capabilities.SetMaxAmsduLength (1); //hardcoded for now (TBD)
+ capabilities.SetLSigProtectionSupport (!m_phy->GetGreenfield ());
+ capabilities.SetMaxAmpduLength (3); //hardcoded for now (TBD)
+ uint64_t maxSupportedRate = 0; //in bit/s
+ for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
{
- maxSupportedRate = (m_phy->McsToWifiMode (i)).GetDataRate ();
+ WifiMode mcs = m_phy->GetMcs (i);
+ capabilities.SetRxMcsBitmask (mcs.GetMcsValue ());
+ if (mcs.GetDataRate (m_phy->GetGuardInterval (), m_phy->GetGuardInterval (), 1) > maxSupportedRate)
+ {
+ maxSupportedRate = mcs.GetDataRate (m_phy->GetGuardInterval (), m_phy->GetGuardInterval (), 1);
+ }
}
+ capabilities.SetRxHighestSupportedDataRate (maxSupportedRate / 1e6); //in Mbit/s
+ capabilities.SetTxMcsSetDefined (m_phy->GetNMcs () > 0);
+ capabilities.SetTxMaxNSpatialStreams (m_phy->GetNumberOfTransmitAntennas ());
}
- capabilities.SetRxHighestSupportedDataRate (maxSupportedRate / 1e6); //in Mbit/s
- capabilities.SetTxMcsSetDefined (m_phy->GetNMcs () > 0);
- capabilities.SetTxMaxNSpatialStreams (m_phy->GetNumberOfTransmitAntennas ());
+ return capabilities;
+}
+
+VhtCapabilities
+ApWifiMac::GetVhtCapabilities (void) const
+{
+ VhtCapabilities capabilities;
+ capabilities.SetVhtSupported (1);
+ if (m_vhtSupported)
+ {
+ if (m_phy->GetChannelWidth () == 160)
+ {
+ capabilities.SetSupportedChannelWidthSet (1);
+ }
+ else
+ {
+ capabilities.SetSupportedChannelWidthSet (0);
+ }
+ capabilities.SetMaxMpduLength (2); //hardcoded for now (TBD)
+ capabilities.SetRxLdpc (m_phy->GetLdpc ());
+ capabilities.SetShortGuardIntervalFor80Mhz ((m_phy->GetChannelWidth () == 80) && m_phy->GetGuardInterval ());
+ capabilities.SetShortGuardIntervalFor160Mhz ((m_phy->GetChannelWidth () == 160) && m_phy->GetGuardInterval ());
+ capabilities.SetMaxAmpduLengthExponent (7); //hardcoded for now (TBD)
+ uint8_t maxMcs = 0;
+ for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
+ {
+ WifiMode mcs = m_phy->GetMcs (i);
+ if (mcs.GetMcsValue () > maxMcs)
+ {
+ maxMcs = mcs.GetMcsValue ();
+ }
+ }
+ capabilities.SetRxMcsMap (maxMcs, 1); //Only 1 SS is currently supported
+ capabilities.SetTxMcsMap (maxMcs, 1); //Only 1 SS is currently supported
+ }
return capabilities;
}
@@ -379,11 +427,15 @@
probe.SetSsid (GetSsid ());
probe.SetSupportedRates (GetSupportedRates ());
probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
probe.SetHtCapabilities (GetHtCapabilities ());
hdr.SetNoOrder ();
}
+ if (m_vhtSupported)
+ {
+ probe.SetVhtCapabilities (GetVhtCapabilities ());
+ }
packet->AddHeader (probe);
//The standard is not clear on the correct queue for management
@@ -418,11 +470,15 @@
assoc.SetSupportedRates (GetSupportedRates ());
assoc.SetStatusCode (code);
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
assoc.SetHtCapabilities (GetHtCapabilities ());
hdr.SetNoOrder ();
}
+ if (m_vhtSupported)
+ {
+ assoc.SetVhtCapabilities (GetVhtCapabilities ());
+ }
packet->AddHeader (assoc);
//The standard is not clear on the correct queue for management
@@ -448,11 +504,15 @@
beacon.SetSsid (GetSsid ());
beacon.SetSupportedRates (GetSupportedRates ());
beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
beacon.SetHtCapabilities (GetHtCapabilities ());
hdr.SetNoOrder ();
}
+ if (m_vhtSupported)
+ {
+ beacon.SetVhtCapabilities (GetVhtCapabilities ());
+ }
packet->AddHeader (beacon);
//The beacon has it's own special queue, so we load it in there
@@ -585,7 +645,12 @@
for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
{
WifiMode mode = m_stationManager->GetBasicMode (i);
- if (!rates.IsSupportedRate (mode.GetDataRate ()))
+ uint32_t channelWidth = m_phy->GetChannelWidth ();
+ if (channelWidth > 20)
+ {
+ channelWidth = 20;
+ }
+ if (!rates.IsSupportedRate (mode.GetDataRate (channelWidth, false, 1)))
{
problem = true;
break;
@@ -597,14 +662,27 @@
HtCapabilities htcapabilities = assocReq.GetHtCapabilities ();
for (uint32_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
{
- uint8_t mcs = m_stationManager->GetBasicMcs (i);
- if (!htcapabilities.IsSupportedMcs (mcs))
+ WifiMode mcs = m_stationManager->GetBasicMcs (i);
+ if (!htcapabilities.IsSupportedMcs (mcs.GetMcsValue ()))
{
problem = true;
break;
}
}
-
+ }
+ if (m_vhtSupported)
+ {
+ //check that the STA supports all MCSs in Basic MCS Set
+ VhtCapabilities vhtcapabilities = assocReq.GetVhtCapabilities ();
+ for (uint32_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
+ {
+ WifiMode mcs = m_stationManager->GetBasicMcs (i);
+ if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
+ {
+ problem = true;
+ break;
+ }
+ }
}
if (problem)
{
@@ -620,7 +698,12 @@
for (uint32_t j = 0; j < m_phy->GetNModes (); j++)
{
WifiMode mode = m_phy->GetMode (j);
- if (rates.IsSupportedRate (mode.GetDataRate ()))
+ uint32_t channelWidth = m_phy->GetChannelWidth ();
+ if (channelWidth > 20)
+ {
+ channelWidth = 20;
+ }
+ if (rates.IsSupportedRate (mode.GetDataRate (channelWidth, false, 1)))
{
m_stationManager->AddSupportedMode (from, mode);
}
@@ -631,15 +714,29 @@
m_stationManager->AddStationHtCapabilities (from,htcapabilities);
for (uint32_t j = 0; j < m_phy->GetNMcs (); j++)
{
- uint8_t mcs = m_phy->GetMcs (j);
- if (htcapabilities.IsSupportedMcs (mcs))
+ WifiMode mcs = m_phy->GetMcs (j);
+ if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HT && htcapabilities.IsSupportedMcs (mcs.GetMcsValue ()))
{
m_stationManager->AddSupportedMcs (from, mcs);
}
}
}
+ if (m_vhtSupported)
+ {
+ VhtCapabilities vhtCapabilities = assocReq.GetVhtCapabilities ();
+ m_stationManager->AddStationVhtCapabilities (from, vhtCapabilities);
+ for (uint32_t i = 0; i < m_phy->GetNMcs (); i++)
+ {
+ WifiMode mcs = m_phy->GetMcs (i);
+ if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VHT && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
+ {
+ m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
+ //here should add a control to add basic MCS when it is implemented
+ }
+ }
+ }
m_stationManager->RecordWaitAssocTxOk (from);
- //send assoc response with success status.
+ // send assoc response with success status.
SendAssocResp (hdr->GetAddr2 (), true);
}
return;
--- a/src/wifi/model/ap-wifi-mac.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/ap-wifi-mac.h Thu Sep 03 22:16:49 2015 +0200
@@ -28,6 +28,7 @@
#include "amsdu-subframe-header.h"
#include "supported-rates.h"
#include "ns3/random-variable-stream.h"
+#include "vht-capabilities.h"
namespace ns3 {
@@ -186,6 +187,12 @@
*/
HtCapabilities GetHtCapabilities (void) const;
/**
+ * Return the VHT capability of the current AP.
+ *
+ * \return the VHT capability that we support
+ */
+ VhtCapabilities GetVhtCapabilities (void) const;
+ /**
* Return an instance of SupportedRates that contains all rates that we support
* including HT rates.
*
--- a/src/wifi/model/aparf-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/aparf-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -127,8 +127,8 @@
void
AparfWifiManager::SetupPhy (Ptr<WifiPhy> phy)
{
- m_minPower = phy->GetTxPowerStart();
- m_maxPower = phy->GetTxPowerEnd();
+ m_minPower = phy->GetTxPowerStart ();
+ m_maxPower = phy->GetTxPowerEnd ();
WifiRemoteStationManager::SetupPhy (phy);
}
@@ -322,8 +322,14 @@
{
NS_LOG_FUNCTION (this << st << size);
AparfWifiRemoteStation *station = (AparfWifiRemoteStation *) st;
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
CheckInit (station);
- return WifiTxVector (GetSupported (station, station->m_rate), station->m_power, GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station));
+ return WifiTxVector (GetSupported (station, station->m_rate), station->m_power, GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
@@ -333,7 +339,13 @@
/// \todo we could/should implement the Arf algorithm for
/// RTS only by picking a single rate within the BasicRateSet.
AparfWifiRemoteStation *station = (AparfWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/arf-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/arf-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -208,7 +208,13 @@
{
NS_LOG_FUNCTION (this << st << size);
ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 1, channelWidth, GetAggregation (station), false);
}
WifiTxVector
@@ -218,7 +224,13 @@
/// \todo we could/should implement the Arf algorithm for
/// RTS only by picking a single rate within the BasicRateSet.
ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/cara-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/cara-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -183,16 +183,29 @@
{
NS_LOG_FUNCTION (this << st << size);
CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
CaraWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
{
NS_LOG_FUNCTION (this << st);
+ CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st;
/// \todo we could/should implement the Arf algorithm for
/// RTS only by picking a single rate within the BasicRateSet.
- return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/constant-rate-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/constant-rate-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -117,14 +117,14 @@
ConstantRateWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size)
{
NS_LOG_FUNCTION (this << st << size);
- return WifiTxVector (m_dataMode, GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st));
+ return WifiTxVector (m_dataMode, GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), 1, 0, GetChannelWidth (st), GetAggregation (st), false);
}
WifiTxVector
ConstantRateWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
{
NS_LOG_FUNCTION (this << st);
- return WifiTxVector (m_ctlMode, GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st));
+ return WifiTxVector (m_ctlMode, GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), 1, 0, GetChannelWidth (st), GetAggregation (st), false);
}
bool
--- a/src/wifi/model/dsss-error-rate-model.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/dsss-error-rate-model.cc Thu Sep 03 22:16:49 2015 +0200
@@ -49,7 +49,7 @@
}
double
-DsssErrorRateModel::GetDsssDqpskSuccessRate (double sinr,uint32_t nbits)
+DsssErrorRateModel::GetDsssDqpskSuccessRate (double sinr, uint32_t nbits)
{
NS_LOG_FUNCTION_NOARGS ();
double EbN0 = sinr * 22000000.0 / 1000000.0 / 2.0; //2 bits per symbol, 1 MSPS
@@ -58,7 +58,7 @@
}
double
-DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (double sinr,uint32_t nbits)
+DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (double sinr, uint32_t nbits)
{
NS_LOG_FUNCTION_NOARGS ();
#ifdef ENABLE_GSL
@@ -92,7 +92,7 @@
}
double
-DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (double sinr,uint32_t nbits)
+DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (double sinr, uint32_t nbits)
{
NS_LOG_FUNCTION_NOARGS ();
#ifdef ENABLE_GSL
--- a/src/wifi/model/edca-txop-n.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/edca-txop-n.cc Thu Sep 03 22:16:49 2015 +0200
@@ -669,6 +669,7 @@
if (!NeedRtsRetransmission ())
{
NS_LOG_DEBUG ("Cts Fail");
+ m_currentPacket = 0;
m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
if (!m_txFailedCallback.IsNull ())
{
@@ -677,10 +678,6 @@
if (GetAmpduExist ())
{
m_low->FlushAggregateQueue ();
-
- NS_LOG_DEBUG ("Transmit Block Ack Request");
- CtrlBAckRequestHeader reqHdr;
- reqHdr.SetType (COMPRESSED_BLOCK_ACK);
uint8_t tid = 0;
if (m_currentHdr.IsQosData ())
{
@@ -690,28 +687,31 @@
{
NS_FATAL_ERROR ("Current packet is not Qos Data");
}
- reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberfor (&m_currentHdr));
- reqHdr.SetTidInfo (tid);
- reqHdr.SetHtImmediateAck (true);
- Ptr<Packet> bar = Create<Packet> ();
- bar->AddHeader (reqHdr);
- Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
- m_currentBar = request;
- WifiMacHeader hdr;
- hdr.SetType (WIFI_MAC_CTL_BACKREQ);
- hdr.SetAddr1 (request.recipient);
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (m_low->GetBssid ());
- hdr.SetDsNotTo ();
- hdr.SetDsNotFrom ();
- hdr.SetNoRetry ();
- hdr.SetNoMoreFragments ();
- m_currentPacket = request.bar;
- m_currentHdr = hdr;
- }
- else
- {
- m_currentPacket = 0;
+
+ if (GetBaAgreementExists (m_currentHdr.GetAddr1 (), tid))
+ {
+ NS_LOG_DEBUG ("Transmit Block Ack Request");
+ CtrlBAckRequestHeader reqHdr;
+ reqHdr.SetType (COMPRESSED_BLOCK_ACK);
+ reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberfor (&m_currentHdr));
+ reqHdr.SetTidInfo (tid);
+ reqHdr.SetHtImmediateAck (true);
+ Ptr<Packet> bar = Create<Packet> ();
+ bar->AddHeader (reqHdr);
+ Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
+ m_currentBar = request;
+ WifiMacHeader hdr;
+ hdr.SetType (WIFI_MAC_CTL_BACKREQ);
+ hdr.SetAddr1 (request.recipient);
+ hdr.SetAddr2 (m_low->GetAddress ());
+ hdr.SetAddr3 (m_low->GetBssid ());
+ hdr.SetDsNotTo ();
+ hdr.SetDsNotFrom ();
+ hdr.SetNoRetry ();
+ hdr.SetNoMoreFragments ();
+ m_currentPacket = request.bar;
+ m_currentHdr = hdr;
+ }
}
//to reset the dcf.
m_dcf->ResetCw ();
@@ -817,20 +817,14 @@
{
NS_LOG_DEBUG ("Ack Fail");
m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+ //to reset the dcf.
+ m_currentPacket = 0;
if (!m_txFailedCallback.IsNull ())
{
m_txFailedCallback (m_currentHdr);
}
- if (!GetAmpduExist ())
+ if (GetAmpduExist ())
{
- //to reset the dcf.
- m_currentPacket = 0;
- }
- else
- {
- NS_LOG_DEBUG ("Transmit Block Ack Request");
- CtrlBAckRequestHeader reqHdr;
- reqHdr.SetType (COMPRESSED_BLOCK_ACK);
uint8_t tid = 0;
if (m_currentHdr.IsQosData ())
{
@@ -840,24 +834,32 @@
{
NS_FATAL_ERROR ("Current packet is not Qos Data");
}
- reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberfor (&m_currentHdr));
- reqHdr.SetTidInfo (tid);
- reqHdr.SetHtImmediateAck (true);
- Ptr<Packet> bar = Create<Packet> ();
- bar->AddHeader (reqHdr);
- Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
- m_currentBar = request;
- WifiMacHeader hdr;
- hdr.SetType (WIFI_MAC_CTL_BACKREQ);
- hdr.SetAddr1 (request.recipient);
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (m_low->GetBssid ());
- hdr.SetDsNotTo ();
- hdr.SetDsNotFrom ();
- hdr.SetNoRetry ();
- hdr.SetNoMoreFragments ();
- m_currentPacket = request.bar;
- m_currentHdr = hdr;
+
+ if (GetBaAgreementExists (m_currentHdr.GetAddr1 (), tid))
+ {
+ //send Block ACK Request in order to shift WinStart at the receiver
+ NS_LOG_DEBUG ("Transmit Block Ack Request");
+ CtrlBAckRequestHeader reqHdr;
+ reqHdr.SetType (COMPRESSED_BLOCK_ACK);
+ reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberfor (&m_currentHdr));
+ reqHdr.SetTidInfo (tid);
+ reqHdr.SetHtImmediateAck (true);
+ Ptr<Packet> bar = Create<Packet> ();
+ bar->AddHeader (reqHdr);
+ Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ());
+ m_currentBar = request;
+ WifiMacHeader hdr;
+ hdr.SetType (WIFI_MAC_CTL_BACKREQ);
+ hdr.SetAddr1 (request.recipient);
+ hdr.SetAddr2 (m_low->GetAddress ());
+ hdr.SetAddr3 (m_low->GetBssid ());
+ hdr.SetDsNotTo ();
+ hdr.SetDsNotFrom ();
+ hdr.SetNoRetry ();
+ hdr.SetNoMoreFragments ();
+ m_currentPacket = request.bar;
+ m_currentHdr = hdr;
+ }
}
m_dcf->ResetCw ();
}
--- a/src/wifi/model/error-rate-model.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/error-rate-model.cc Thu Sep 03 22:16:49 2015 +0200
@@ -41,11 +41,13 @@
low = 1e-25;
high = 1e25;
precision = 1e-12;
+ WifiTxVector txVector;
+ txVector.SetMode (txMode);
while (high - low > precision)
{
NS_ASSERT (high >= low);
double middle = low + (high - low) / 2;
- if ((1 - GetChunkSuccessRate (txMode, middle, 1)) > ber)
+ if ((1 - GetChunkSuccessRate (txMode, txVector, middle, 1)) > ber)
{
low = middle;
}
--- a/src/wifi/model/error-rate-model.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/error-rate-model.h Thu Sep 03 22:16:49 2015 +0200
@@ -23,6 +23,7 @@
#include <stdint.h>
#include "wifi-mode.h"
+#include "wifi-tx-vector.h"
#include "ns3/object.h"
namespace ns3 {
@@ -54,12 +55,13 @@
* the mode, the SNR, and the size of the chunk.
*
* \param mode the Wi-Fi mode the chunk is sent
+ * \param txvector TXVECTOR of the transmission
* \param snr the SNR of the chunk
* \param nbits the number of bits in this chunk
*
* \return probability of successfully receiving the chunk
*/
- virtual double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const = 0;
+ virtual double GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const = 0;
};
} //namespace ns3
--- a/src/wifi/model/ideal-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/ideal-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -169,7 +169,13 @@
maxMode = mode;
}
}
- return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
@@ -192,7 +198,13 @@
maxMode = mode;
}
}
- return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/interference-helper.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/interference-helper.cc Thu Sep 03 22:16:49 2015 +0200
@@ -234,17 +234,17 @@
double
-InterferenceHelper::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
+InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint32_t channelWidth) const
{
//thermal noise at 290K in J/s = W
static const double BOLTZMANN = 1.3803e-23;
//Nt is the power of thermal noise in W
- double Nt = BOLTZMANN * 290.0 * mode.GetBandwidth ();
+ double Nt = BOLTZMANN * 290.0 * channelWidth * 1000000;
//receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
double noiseFloor = m_noiseFigure * Nt;
double noise = noiseFloor + noiseInterference;
double snr = signal / noise; //linear scale
- NS_LOG_DEBUG ("signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr(linear)=" << snr);
+ NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr(linear)=" << snr);
return snr;
}
@@ -267,15 +267,15 @@
}
double
-InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const
+InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, WifiTxVector txVector) const
{
if (duration == NanoSeconds (0))
{
return 1.0;
}
- uint32_t rate = mode.GetPhyRate ();
+ uint32_t rate = mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1);
uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
- double csr = m_errorRateModel->GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
+ double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, (uint32_t)nbits);
return csr;
}
@@ -288,10 +288,10 @@
Time previous = (*j).GetTime ();
WifiMode payloadMode = event->GetPayloadMode ();
WifiPreamble preamble = event->GetPreambleType ();
- Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (payloadMode, preamble); //packet start time + preamble
- Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (payloadMode, preamble); //packet start time + preamble + L-SIG
- Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG
- Time plcpPayloadStart = plcpHtTrainingSymbolsStart + WifiPhy::GetPlcpHtTrainingSymbolDuration (preamble,event->GetTxVector ()); //packet start time + preamble + L-SIG + HT-SIG + HT Training
+ Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (event->GetTxVector (), preamble); //packet start time + preamble
+ Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (event->GetTxVector (), preamble); //packet start time + preamble + L-SIG
+ Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpVhtSigA1Duration (preamble) + WifiPhy::GetPlcpVhtSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2)
+ Time plcpPayloadStart = plcpHtTrainingSymbolsStart + WifiPhy::GetPlcpHtTrainingSymbolDuration (preamble, event->GetTxVector ()) + WifiPhy::GetPlcpVhtSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2) + (V)HT Training + VHT-SIG-B
double noiseInterferenceW = (*j).GetDelta ();
double powerW = event->GetRxPowerW ();
j++;
@@ -305,9 +305,9 @@
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- payloadMode),
+ event->GetTxVector ().GetChannelWidth ()),
current - previous,
- payloadMode);
+ payloadMode, event->GetTxVector ());
NS_LOG_DEBUG ("Both previous and current point to the payload: mode=" << payloadMode << ", psr=" << psr);
}
@@ -316,9 +316,9 @@
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- payloadMode),
+ event->GetTxVector ().GetChannelWidth ()),
current - plcpPayloadStart,
- payloadMode);
+ payloadMode, event->GetTxVector ());
NS_LOG_DEBUG ("previous is before payload and current is in the payload: mode=" << payloadMode << ", psr=" << psr);
}
@@ -344,13 +344,18 @@
if (preamble == WIFI_PREAMBLE_HT_MF)
{
//mode for PLCP header fields sent with HT modulation
- htHeaderMode = WifiPhy::GetHTPlcpHeaderMode (payloadMode);
+ htHeaderMode = WifiPhy::GetHtPlcpHeaderMode (payloadMode);
}
- WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble);
- Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (payloadMode, preamble); //packet start time + preamble
- Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (payloadMode, preamble); //packet start time + preamble + L-SIG
- Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG
- Time plcpPayloadStart = plcpHtTrainingSymbolsStart + WifiPhy::GetPlcpHtTrainingSymbolDuration (preamble, event->GetTxVector ()); //packet start time + preamble + L-SIG + HT-SIG + HT Training
+ else if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ //mode for PLCP header fields sent with VHT modulation
+ htHeaderMode = WifiPhy::GetVhtPlcpHeaderMode (payloadMode);
+ }
+ WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble, event->GetTxVector ());
+ Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (event->GetTxVector (), preamble); //packet start time + preamble
+ Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (event->GetTxVector (), preamble); //packet start time + preamble + L-SIG
+ Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpVhtSigA1Duration (preamble) + WifiPhy::GetPlcpVhtSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2)
+ Time plcpPayloadStart = plcpHtTrainingSymbolsStart + WifiPhy::GetPlcpHtTrainingSymbolDuration (preamble, event->GetTxVector ()) + WifiPhy::GetPlcpVhtSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2) + (V)HT Training + VHT-SIG-B
double noiseInterferenceW = (*j).GetDelta ();
double powerW = event->GetRxPowerW ();
j++;
@@ -365,8 +370,8 @@
psr *= 1;
NS_LOG_DEBUG ("Case 1 - previous and current after playload start: nothing to do");
}
- //Case 2: previous is in HT-SIG or in HT training: Non HT will not enter here since it didn't enter in the last two and they are all the same for non HT
- else if (previous >= plcpHsigHeaderStart)
+ //Case 2: previous is in (V)HT training or in VHT-SIG-B: Non (V)HT will not enter here since it didn't enter in the last two and they are all the same for non (V)HT
+ else if (previous >= plcpHtTrainingSymbolsStart)
{
NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
//Case 2a: current after payload start
@@ -374,155 +379,400 @@
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- htHeaderMode),
+ event->GetTxVector ().GetChannelWidth ()),
plcpPayloadStart - previous,
- htHeaderMode);
+ htHeaderMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 2a - previous is in HT-SIG or in HT training and current after payload start: mode=" << htHeaderMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 2a - previous is in (V)HT training or in VHT-SIG-B and current after payload start: mode=" << htHeaderMode << ", psr=" << psr);
}
- //Case 2b: current is in HT-SIG or in HT training
+ //Case 2b: current is in (V)HT training or in VHT-SIG-B
else
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- htHeaderMode),
+ event->GetTxVector ().GetChannelWidth ()),
current - previous,
- htHeaderMode);
+ htHeaderMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 2b - previous is in HT-SIG or in HT training and current is in HT-SIG or in HT training: mode=" << htHeaderMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 2b - previous is in (V)HT training or in VHT-SIG-B and current is in (V)HT training or in VHT-SIG-B: mode=" << htHeaderMode << ", psr=" << psr);
}
}
- //Case 3: previous in L-SIG: GF will not reach here because it will execute the previous if and exit
+ //Case 3: previous is in HT-SIG or VHT-SIG-A: Non (V)HT will not enter here since it didn't enter in the last two and they are all the same for non (V)HT
+ else if (previous >= plcpHsigHeaderStart)
+ {
+ NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
+ //Case 3a: current after payload start
+ if (current >= plcpPayloadStart)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpPayloadStart - plcpHtTrainingSymbolsStart,
+ htHeaderMode, event->GetTxVector ());
+
+ //Case 3ai: VHT format
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ //VHT-SIG-A is sent using legacy OFDM modulation
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - previous,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 3ai - previous is in VHT-SIG-A and current after payload start: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 3aii: HT mixed format of HT greenfield
+ else
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - previous,
+ htHeaderMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 3aii - previous is in HT-SIG and current after payload start: mode=" << htHeaderMode << ", psr=" << psr);
+ }
+ }
+ //Case 3b: current is in (V)HT training or in VHT-SIG-B
+ else if (current >= plcpHtTrainingSymbolsStart)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHtTrainingSymbolsStart,
+ htHeaderMode, event->GetTxVector ());
+
+ //Case 3bi: VHT format
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ //VHT-SIG-A is sent using legacy OFDM modulation
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - previous,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 3bi - previous is in VHT-SIG-A and current is in VHT training or in VHT-SIG-B: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 3bii: HT mixed format of HT greenfield
+ else
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - previous,
+ htHeaderMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 3bii - previous is in HT-SIG and current is in HT training: mode=" << htHeaderMode << ", psr=" << psr);
+ }
+ }
+ //Case 3c: current with previous in HT-SIG or VHT-SIG-A
+ else
+ {
+ //Case 3bi: VHT format
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ //VHT-SIG-A is sent using legacy OFDM modulation
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - previous,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 3ci - previous with current in VHT-SIG-A: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 3bii: HT mixed format of HT greenfield
+ else
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - previous,
+ htHeaderMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 3cii - previous with current in HT-SIG: mode=" << htHeaderMode << ", psr=" << psr);
+ }
+ }
+ }
+ //Case 4: previous in L-SIG: HT GF will not reach here because it will execute the previous if and exit
else if (previous >= plcpHeaderStart)
{
NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
- //Case 3a: current after payload start
+ //Case 4a: current after payload start
if (current >= plcpPayloadStart)
{
- //Case 3ai: Non HT format (No HT-SIG or Training Symbols)
+ //Case 4ai: Non (V)HT format
if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
+ event->GetTxVector ().GetChannelWidth ()),
plcpPayloadStart - previous,
- headerMode);
+ headerMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 3ai - previous in L-SIG and current after payload start: mode=" << headerMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 4ai - previous in L-SIG and current after payload start: mode=" << headerMode << ", psr=" << psr);
}
- //Case 3aii: HT mixed format
+ //Case 4aii: VHT format
+ else if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpPayloadStart - plcpHtTrainingSymbolsStart,
+ htHeaderMode, event->GetTxVector ());
+
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - previous,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 4aii - previous is in L-SIG and current after payload start: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 4aiii: HT mixed format
else
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- htHeaderMode),
+ event->GetTxVector ().GetChannelWidth ()),
plcpPayloadStart - plcpHsigHeaderStart,
- htHeaderMode);
+ htHeaderMode, event->GetTxVector ());
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
+ event->GetTxVector ().GetChannelWidth ()),
plcpHsigHeaderStart - previous,
- headerMode);
+ headerMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 3aii - previous in L-SIG and current after payload start: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 4aiii - previous in L-SIG and current after payload start: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
}
}
- //Case 3b: current in HT-SIG or in HT training symbol. Non HT will not come here since it went in previous if or if the previous if is not true this will be not true
+ //Case 4b: current is in (V)HT training or in VHT-SIG-B. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
+ else if (current >= plcpHtTrainingSymbolsStart)
+ {
+ NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
+
+ //Case 4bi: VHT format
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHtTrainingSymbolsStart,
+ htHeaderMode, event->GetTxVector ());
+
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - previous,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 4bi - previous is in L-SIG and current in VHT training or in VHT-SIG-B: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 4bii: HT mixed format
+ else
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHsigHeaderStart,
+ htHeaderMode, event->GetTxVector ());
+
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHsigHeaderStart - previous,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 4bii - previous in L-SIG and current in HT training: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ }
+ }
+ //Case 4c: current in HT-SIG or in VHT-SIG-A. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
else if (current >= plcpHsigHeaderStart)
{
NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- htHeaderMode),
- current - plcpHsigHeaderStart,
- htHeaderMode);
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- headerMode),
- plcpHsigHeaderStart - previous,
- headerMode);
+ //Case 4ci: VHT format
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - previous,
+ headerMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 3b - previous in L-SIG and current in HT-SIG or in HT training symbol: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 4ci - previous is in L-SIG and current in VHT-SIG-A: mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 4cii: HT mixed format
+ else
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHsigHeaderStart,
+ htHeaderMode, event->GetTxVector ());
+
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHsigHeaderStart - previous,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 4cii - previous in L-SIG and current in HT-SIG: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ }
}
- //Case 3c: current with previous in L-SIG
+ //Case 4d: current with previous in L-SIG
else
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
+ event->GetTxVector ().GetChannelWidth ()),
current - previous,
- headerMode);
+ headerMode, event->GetTxVector ());
NS_LOG_DEBUG ("Case 3c - current with previous in L-SIG: mode=" << headerMode << ", psr=" << psr);
}
}
- //Case 4: previous is in the preamble works for all cases
+ //Case 5: previous is in the preamble works for all cases
else
{
+ //Case 5a: current after payload start
if (current >= plcpPayloadStart)
{
- //Non HT format (No HT-SIG or Training Symbols)
+ //Case 5ai: Non HT format (No HT-SIG or Training Symbols)
if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
+ event->GetTxVector ().GetChannelWidth ()),
plcpPayloadStart - plcpHeaderStart,
- headerMode);
+ headerMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 4a - previous is in the preamble: mode=" << headerMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 5a - previous is in the preamble and current is after payload start: mode=" << headerMode << ", psr=" << psr);
}
- //HT format
+ //Case 5aii: VHT format
+ else if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpPayloadStart - plcpHtTrainingSymbolsStart,
+ htHeaderMode, event->GetTxVector ());
+
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - plcpHeaderStart,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 5aii - previous is in the preamble and current is after payload start: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
+ }
+
+ //Case 5aiii: HT format
else
{
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- htHeaderMode),
+ event->GetTxVector ().GetChannelWidth ()),
plcpPayloadStart - plcpHsigHeaderStart,
- htHeaderMode);
+ htHeaderMode, event->GetTxVector ());
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
+ event->GetTxVector ().GetChannelWidth ()),
plcpHsigHeaderStart - plcpHeaderStart, //HT GF: plcpHsigHeaderStart - plcpHeaderStart = 0
- headerMode);
+ headerMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 4a - previous is in the preamble: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 4a - previous is in the preamble and current is after payload start: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
}
}
- //non HT will not come here
+ //Case 5b: current is in (V)HT training or in VHT-SIG-B. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
+ else if (current >= plcpHtTrainingSymbolsStart)
+ {
+ NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
+
+ //Case 5bi: VHT format
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHtTrainingSymbolsStart,
+ htHeaderMode, event->GetTxVector ());
+
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHtTrainingSymbolsStart - plcpHeaderStart,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 5bi - previous is in the preamble and current in VHT training or in VHT-SIG-B: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 45ii: HT mixed format
+ else
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHsigHeaderStart,
+ htHeaderMode, event->GetTxVector ());
+
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHsigHeaderStart - plcpHeaderStart,
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 5bii - previous is in the preamble and current in HT training: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ }
+ }
+ //Case 5c: current in HT-SIG or in VHT-SIG-A. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
else if (current >= plcpHsigHeaderStart)
{
NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- htHeaderMode),
- current - plcpHsigHeaderStart,
- htHeaderMode);
+ //Case 5ci: VHT format
+ if (preamble == WIFI_PREAMBLE_VHT)
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHeaderStart,
+ headerMode, event->GetTxVector ());
- psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
- noiseInterferenceW,
- headerMode),
- plcpHsigHeaderStart - plcpHeaderStart, //HT GF: plcpHsigHeaderStart - plcpHeaderStart = 0
- headerMode);
+ NS_LOG_DEBUG ("Case 5ci - previous is in preamble and current in VHT-SIG-A: mode=" << headerMode << ", psr=" << psr);
+ }
+ //Case 5cii: HT mixed format
+ else
+ {
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ current - plcpHsigHeaderStart,
+ htHeaderMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 4b - previous is in the preamble: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
+ noiseInterferenceW,
+ event->GetTxVector ().GetChannelWidth ()),
+ plcpHsigHeaderStart - plcpHeaderStart, //HT GF: plcpHsigHeaderStart - plcpHeaderStart = 0
+ headerMode, event->GetTxVector ());
+
+ NS_LOG_DEBUG ("Case 5cii - previous in preamble and current in HT-SIG: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
+ }
}
- //GF will not come here
+ //Case 5d: current is in L-SIG. HT GF will not come here
else if (current >= plcpHeaderStart)
{
NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
noiseInterferenceW,
- headerMode),
+ event->GetTxVector ().GetChannelWidth ()),
current - plcpHeaderStart,
- headerMode);
+ headerMode, event->GetTxVector ());
- NS_LOG_DEBUG ("Case 4c - previous is in the preamble: mode=" << headerMode << ", psr=" << psr);
+ NS_LOG_DEBUG ("Case 5d - previous is in the preamble and current is in L-SIG: mode=" << headerMode << ", psr=" << psr);
}
}
@@ -542,7 +792,7 @@
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
double snr = CalculateSnr (event->GetRxPowerW (),
noiseInterferenceW,
- event->GetPayloadMode ());
+ event->GetTxVector ().GetChannelWidth ());
/* calculate the SNIR at the start of the packet and accumulate
* all SNIR changes in the snir vector.
@@ -562,7 +812,7 @@
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
double snr = CalculateSnr (event->GetRxPowerW (),
noiseInterferenceW,
- WifiPhy::GetPlcpHeaderMode (event->GetPayloadMode (), event->GetPreambleType ()));
+ event->GetTxVector ().GetChannelWidth ());
/* calculate the SNIR at the start of the plcp header and accumulate
* all SNIR changes in the snir vector.
--- a/src/wifi/model/interference-helper.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/interference-helper.h Thu Sep 03 22:16:49 2015 +0200
@@ -285,11 +285,11 @@
*
* \param signal
* \param noiseInterference
- * \param mode
+ * \param channelWidth
*
* \return SNR in liear ratio
*/
- double CalculateSnr (double signal, double noiseInterference, WifiMode mode) const;
+ double CalculateSnr (double signal, double noiseInterference, uint32_t channelWidth) const;
/**
* Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode.
* The duration and mode are used to calculate how many bits are present in the chunk.
@@ -297,10 +297,11 @@
* \param snir SINR
* \param duration
* \param mode
+ * \param txVector
*
* \return the success rate
*/
- double CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const;
+ double CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, WifiTxVector txVector) const;
/**
* Calculate the error rate of the given plcp payload. The plcp payload can be divided into
* multiple chunks (e.g. due to interference from other transmissions).
--- a/src/wifi/model/mac-low.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/mac-low.cc Thu Sep 03 22:16:49 2015 +0200
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Mirko Banchi <mk.banchi@gmail.com>
*/
#include "ns3/assert.h"
@@ -27,7 +27,6 @@
#include "ns3/log.h"
#include "ns3/node.h"
#include "ns3/double.h"
-
#include "mac-low.h"
#include "wifi-phy.h"
#include "wifi-mac-trailer.h"
@@ -37,12 +36,11 @@
#include "yans-wifi-phy.h"
#include "ampdu-tag.h"
#include "wifi-mac-queue.h"
-#include "mpdu-aggregator.h"
+#include "mpdu-standard-aggregator.h"
#undef NS_LOG_APPEND_CONTEXT
#define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
-
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("MacLow");
@@ -68,6 +66,7 @@
MacLowDcfListener::~MacLowDcfListener ()
{
}
+
MacLowAggregationCapableTransmissionListener::MacLowAggregationCapableTransmissionListener ()
{
}
@@ -532,8 +531,8 @@
void
MacLow::ResetPhy (void)
{
- m_phy->SetReceiveOkCallback (MakeNullCallback<void,Ptr<Packet>, double, WifiTxVector, enum WifiPreamble> ());
- m_phy->SetReceiveErrorCallback (MakeNullCallback<void,Ptr<const Packet>, double> ());
+ m_phy->SetReceiveOkCallback (MakeNullCallback<void, Ptr<Packet>, double, WifiTxVector, enum WifiPreamble> ());
+ m_phy->SetReceiveErrorCallback (MakeNullCallback<void, Ptr<const Packet>, double> ());
RemovePhyMacLowListener (m_phy);
m_phy = 0;
}
@@ -740,33 +739,58 @@
* QapScheduler has taken access to the channel from
* one of the Edca of the QAP.
*/
+ m_currentPacket = packet->Copy ();
m_currentHdr = *hdr;
CancelAllEvents ();
m_listener = listener;
m_txParams = params;
- if (m_aggregateQueue->GetSize () == 0)
+ if (!m_currentHdr.IsQosData () && !m_currentHdr.IsBlockAck () && !m_currentHdr.IsBlockAckReq ())
+ {
+ //This is mainly encountered when a higher priority control frame (such as beacons)
+ //is sent between A-MPDU transmissions. It avoids to unexpectedly flush the aggregate
+ //queue when previous RTS request has failed.
+ m_ampdu = false;
+ }
+ else if (m_aggregateQueue->GetSize () > 0)
{
- m_currentPacket = packet->Copy ();
- m_ampdu = IsAmpdu (m_currentPacket, m_currentHdr);
+ //m_aggregateQueue > 0 occurs when a RTS/CTS exchange failed before an A-MPDU transmission.
+ //In that case, we transmit the same A-MPDU as previously.
+ m_sentMpdus = m_aggregateQueue->GetSize ();
+ m_ampdu = true;
+ if (m_sentMpdus > 1)
+ {
+ m_txParams.EnableCompressedBlockAck ();
+ }
+ else
+ {
+ //VHT single MPDUs are followed by normal ACKs
+ m_txParams.EnableAck ();
+ }
}
else
{
- /*m_aggregateQueue > 0 occurs when a RTS/CTS exchange failed before an A-MPDU transmission.
- *In that case, we transmit the same A-MPDU as previously.
- */
- m_sentMpdus = m_aggregateQueue->GetSize ();
- m_ampdu = true;
+ //Perform MPDU aggregation if possible
+ m_ampdu = IsAmpdu (m_currentPacket, m_currentHdr);
+ if (m_ampdu)
+ {
+ AmpduTag ampdu;
+ m_currentPacket->PeekPacketTag (ampdu);
+ if (ampdu.GetNoOfMpdus () > 1)
+ {
+ m_txParams.EnableCompressedBlockAck ();
+ }
+ else
+ {
+ //VHT single MPDUs are followed by normal ACKs
+ m_txParams.EnableAck ();
+ }
+ }
}
NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
- if (m_ampdu)
- {
- m_txParams.EnableCompressedBlockAck ();
- }
-
if (m_txParams.MustSendRts ())
{
SendRtsForPacket ();
@@ -964,6 +988,7 @@
rxSnr, txVector.GetMode (), tag.Get ());
FlushAggregateQueue ();
+ m_ampdu = false;
bool gotAck = false;
if (m_txParams.MustWaitNormalAck ()
@@ -1130,6 +1155,7 @@
hdr.GetDuration (),
txVector.GetMode (),
rxSnr);
+ m_receivedAtLeastOneMpdu = false;
}
}
goto rxPacket;
@@ -1245,7 +1271,7 @@
Time
MacLow::GetAckDuration (WifiTxVector ackTxVector) const
{
- NS_ASSERT (ackTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); // ACK should always use non-HT PPDU (HT PPDU cases not supported yet)
+ NS_ASSERT (ackTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); //ACK should always use non-HT PPDU (HT PPDU cases not supported yet)
return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, WIFI_PREAMBLE_LONG, m_phy->GetFrequency (), 0, 0);
}
@@ -1278,7 +1304,7 @@
Time
MacLow::GetCtsDuration (WifiTxVector ctsTxVector) const
{
- NS_ASSERT (ctsTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); // CTS should always use non-HT PPDU (HT PPDU cases not supported yet)
+ NS_ASSERT (ctsTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); //CTS should always use non-HT PPDU (HT PPDU cases not supported yet)
return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, WIFI_PREAMBLE_LONG, m_phy->GetFrequency (), 0, 0);
}
@@ -1384,7 +1410,11 @@
txTime += Time (GetSifs () * 2);
}
WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
- if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+ if (dataTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT)
+ {
+ preamble = WIFI_PREAMBLE_VHT;
+ }
+ else if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
{
preamble = WIFI_PREAMBLE_HT_GF;
}
@@ -1416,6 +1446,10 @@
{
WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
WifiPreamble preamble;
+ if (dataTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT)
+ {
+ preamble = WIFI_PREAMBLE_VHT;
+ }
if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
{
preamble = WIFI_PREAMBLE_HT_GF;
@@ -1443,7 +1477,7 @@
if (hdr.IsCfpoll ()
&& hdr.GetAddr2 () == m_bssid)
{
- // see section 9.3.2.2 802.11-1999
+ //see section 9.3.2.2 802.11-1999
DoNavResetNow (duration);
return;
}
@@ -1572,13 +1606,20 @@
WifiMacHeader newHdr;
WifiMacTrailer fcs;
uint32_t queueSize = m_aggregateQueue->GetSize ();
+ bool vhtSingleMpdu = false;
bool last = false;
uint8_t packetType = 0;
+
+ if (queueSize == 1)
+ {
+ vhtSingleMpdu = true;
+ }
+
//Add packet tag
AmpduTag ampdutag;
ampdutag.SetAmpdu (true);
Time delay = Seconds (0);
- if (queueSize > 1)
+ if (queueSize > 1 || vhtSingleMpdu)
{
txVector.SetAggregation (true);
}
@@ -1594,14 +1635,21 @@
last = true;
packetType = 2;
}
- m_mpduAggregator->AddHeaderAndPad (newPacket, last);
+ m_mpduAggregator->AddHeaderAndPad (newPacket, last, vhtSingleMpdu);
ampdutag.SetNoOfMpdus (queueSize);
newPacket->AddPacketTag (ampdutag);
if (delay == Seconds (0))
{
- NS_LOG_DEBUG ("Sending MPDU as part of A-MPDU");
- packetType = 1;
+ if (!vhtSingleMpdu)
+ {
+ NS_LOG_DEBUG ("Sending MPDU as part of A-MPDU");
+ packetType = 1;
+ }
+ else
+ {
+ packetType = 0;
+ }
m_phy->SendPacket (newPacket, txVector, preamble, packetType, m_mpduReferenceNumber);
}
else
@@ -1801,8 +1849,12 @@
{
WifiPreamble preamble;
+ if (dataTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT)
+ {
+ preamble = WIFI_PREAMBLE_VHT;
+ }
//Since it is data then it can have format = GF
- if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+ else if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
{
preamble = WIFI_PREAMBLE_HT_GF;
}
@@ -1881,8 +1933,11 @@
/* send this packet directly. No RTS is needed. */
WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
WifiPreamble preamble;
-
- if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+ if (dataTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT)
+ {
+ preamble = WIFI_PREAMBLE_VHT;
+ }
+ else if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
{
//In the future has to make sure that receiver has greenfield enabled
preamble = WIFI_PREAMBLE_HT_GF;
@@ -2049,6 +2104,7 @@
&MacLow::SendDataAfterCts, this,
cts.GetAddr1 (),
duration);
+
}
void
@@ -2080,7 +2136,6 @@
tag.Set (rtsSnr);
packet->AddPacketTag (tag);
- //CTS should always use non-HT PPDU (HT PPDU cases not supported yet)
ForwardDown (packet, &cts, ctsTxVector, WIFI_PREAMBLE_LONG);
}
@@ -2108,7 +2163,11 @@
}
WifiPreamble preamble;
- if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+ if (dataTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT)
+ {
+ preamble = WIFI_PREAMBLE_VHT;
+ }
+ else if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
{
//In the future has to make sure that receiver has greenfield enabled
preamble = WIFI_PREAMBLE_HT_GF;
@@ -2243,7 +2302,7 @@
bool
MacLow::ReceiveMpdu (Ptr<Packet> packet, WifiMacHeader hdr)
{
- if (m_stationManager->HasHtSupported ())
+ if (m_stationManager->HasHtSupported () || m_stationManager->HasVhtSupported ())
{
Mac48Address originator = hdr.GetAddr2 ();
uint8_t tid = 0;
@@ -2586,7 +2645,7 @@
(*i).second.FillBlockAckBitmap (&blockAck);
NS_LOG_DEBUG ("Got block Ack Req with seq " << reqHdr.GetStartingSequence ());
- if (!m_stationManager->HasHtSupported ())
+ if (!m_stationManager->HasHtSupported () && !m_stationManager->HasVhtSupported ())
{
/* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
* See 9.10.3 in IEEE 802.11e standard.
@@ -2660,7 +2719,7 @@
m_currentTxVector = txVector;
AmpduTag ampdu;
bool normalAck = false;
- bool ampduSubframe = false;
+ bool ampduSubframe = false; //flag indicating the packet belongs to an A-MPDU and is not a VHT single MPDU
if (aggregatedPacket->RemovePacketTag (ampdu))
{
ampduSubframe = true;
@@ -2672,6 +2731,14 @@
NS_LOG_DEBUG ("duration/id=" << firsthdr.GetDuration ());
NotifyNav ((*n).first, firsthdr, preamble);
+ bool vhtSingleMpdu = (*n).second.GetEof ();
+ if (vhtSingleMpdu == true)
+ {
+ //If the MPDU is sent as a VHT single MPDU (EOF=1 in A-MPDU subframe header), then the responder sends an ACK.
+ NS_LOG_DEBUG ("Receive VHT single MPDU");
+ ampduSubframe = false;
+ }
+
if (firsthdr.GetAddr1 () == m_self)
{
m_receivedAtLeastOneMpdu = true;
@@ -2695,7 +2762,7 @@
}
}
- if (normalAck && (ampdu.GetNoOfMpdus () == 1))
+ if (normalAck && (ampdu.GetNoOfMpdus () == 1) && !vhtSingleMpdu)
{
//send block Ack
if (firsthdr.IsBlockAckReq ())
@@ -2735,7 +2802,11 @@
{
WifiPreamble preamble;
WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
- if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
+ if (dataTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT)
+ {
+ preamble = WIFI_PREAMBLE_VHT;
+ }
+ else if (m_phy->GetGreenfield () && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
{
preamble = WIFI_PREAMBLE_HT_GF;
}
@@ -2778,6 +2849,7 @@
Ptr<Packet> newPacket, tempPacket;
WifiMacHeader peekedHdr;
newPacket = packet->Copy ();
+ Ptr<Packet> currentAggregatedPacket;
//missing hdr.IsAck() since we have no means of knowing the Tid of the Ack yet
if (hdr.IsQosData () || hdr.IsBlockAck ()|| hdr.IsBlockAckReq ())
{
@@ -2797,7 +2869,7 @@
{
/* here is performed mpdu aggregation */
/* MSDU aggregation happened in edca if the user asked for it so m_currentPacket may contains a normal packet or a A-MSDU*/
- Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
+ currentAggregatedPacket = Create<Packet> ();
peekedHdr = hdr;
uint16_t startingSequenceNumber = 0;
uint16_t currentSequenceNumber = 0;
@@ -2980,6 +3052,7 @@
}
}
}
+
if (isAmpdu)
{
if (hdr.IsBlockAckReq ())
@@ -3003,7 +3076,6 @@
ampdutag.SetNoOfMpdus (i);
newPacket = currentAggregatedPacket;
newPacket->AddPacketTag (ampdutag);
- currentAggregatedPacket = 0;
NS_LOG_DEBUG ("tx unicast A-MPDU");
listenerIt->second->SetAmpdu (true);
}
@@ -3018,6 +3090,37 @@
}
}
}
+ //VHT single MPDU operation
+ WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
+ if (!isAmpdu && dataTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT && hdr.IsQosData ())
+ {
+ peekedHdr = hdr;
+ peekedHdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+
+ currentAggregatedPacket = Create<Packet> ();
+ m_mpduAggregator->AggregateVhtSingleMpdu (packet, currentAggregatedPacket);
+ m_aggregateQueue->Enqueue (packet, peekedHdr);
+ m_sentMpdus = 1;
+
+ if (listenerIt->second->GetBlockAckAgreementExists (hdr.GetAddr1 (), tid))
+ {
+ listenerIt->second->CompleteTransfer (peekedHdr.GetAddr1 (), tid);
+ }
+
+ //Add packet tag
+ AmpduTag ampdutag;
+ ampdutag.SetAmpdu (true);
+ ampdutag.SetNoOfMpdus (1);
+
+ newPacket = currentAggregatedPacket;
+ newPacket->AddHeader (peekedHdr);
+ WifiMacTrailer fcs;
+ newPacket->AddTrailer (fcs);
+ newPacket->AddPacketTag (ampdutag);
+
+ NS_LOG_DEBUG ("tx unicast VHT single MPDU with sequence number " << hdr.GetSequenceNumber ());
+ listenerIt->second->SetAmpdu (true);
+ }
}
}
return newPacket;
@@ -3059,7 +3162,7 @@
std::map<AcIndex, MacLowAggregationCapableTransmissionListener*>::const_iterator listenerIt = m_edcaListeners.find (ac);
NS_ASSERT (listenerIt != m_edcaListeners.end ());
queue = listenerIt->second->GetQueue ();
-
+
Ptr<const Packet> peekedPacket = queue->DequeueByTidAndAddress (hdr, hdr->GetQosTid (),
WifiMacHeader::ADDR1, hdr->GetAddr1 ());
--- a/src/wifi/model/mac-low.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/mac-low.h Thu Sep 03 22:16:49 2015 +0200
@@ -1284,7 +1284,6 @@
*/
Ptr<Packet> PerformMsduAggregation (Ptr<const Packet> packet, WifiMacHeader *hdr, Time *tstamp, Ptr<Packet> currentAmpduPacket, uint16_t blockAckSize);
-
Ptr<WifiPhy> m_phy; //!< Pointer to WifiPhy (actually send/receives frames)
Ptr<WifiRemoteStationManager> m_stationManager; //!< Pointer to WifiRemoteStationManager (rate control)
MacLowRxCallback m_rxCallback; //!< Callback to pass packet up
--- a/src/wifi/model/mgt-headers.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/mgt-headers.cc Thu Sep 03 22:16:49 2015 +0200
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Mirko Banchi <mk.banchi@gmail.com>
*/
#include <sstream>
@@ -67,6 +67,18 @@
return m_htCapability;
}
+void
+MgtProbeRequestHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities)
+{
+ m_vhtCapability = vhtcapabilities;
+}
+
+VhtCapabilities
+MgtProbeRequestHeader::GetVhtCapabilities (void) const
+{
+ return m_vhtCapability;
+}
+
SupportedRates
MgtProbeRequestHeader::GetSupportedRates (void) const
{
@@ -81,6 +93,7 @@
size += m_rates.GetSerializedSize ();
size += m_rates.extended.GetSerializedSize ();
size += m_htCapability.GetSerializedSize ();
+ size += m_vhtCapability.GetSerializedSize ();
return size;
}
@@ -106,7 +119,8 @@
{
os << "ssid=" << m_ssid << ", "
<< "rates=" << m_rates << ", "
- << "HT Capabilities=" << m_htCapability;
+ << "HT Capabilities=" << m_htCapability << " , "
+ << "VHT Capabilities= " << m_vhtCapability;
}
void
@@ -117,6 +131,7 @@
i = m_rates.Serialize (i);
i = m_rates.extended.Serialize (i);
i = m_htCapability.Serialize (i);
+ i = m_vhtCapability.Serialize (i);
}
uint32_t
@@ -127,6 +142,7 @@
i = m_rates.Deserialize (i);
i = m_rates.extended.DeserializeIfPresent (i);
i = m_htCapability.DeserializeIfPresent (i);
+ i = m_vhtCapability.DeserializeIfPresent (i);
return i.GetDistanceFrom (start);
}
@@ -182,6 +198,18 @@
}
void
+MgtProbeResponseHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities)
+{
+ m_vhtCapability = vhtcapabilities;
+}
+
+VhtCapabilities
+MgtProbeResponseHeader::GetVhtCapabilities (void) const
+{
+ return m_vhtCapability;
+}
+
+void
MgtProbeResponseHeader::SetSsid (Ssid ssid)
{
m_ssid = ssid;
@@ -228,15 +256,19 @@
//size += 3; //ds parameter set
size += m_rates.extended.GetSerializedSize ();
size += m_htCapability.GetSerializedSize ();
+ size += m_vhtCapability.GetSerializedSize ();
return size;
}
+
void
MgtProbeResponseHeader::Print (std::ostream &os) const
{
os << "ssid=" << m_ssid << ", "
<< "rates=" << m_rates << ", "
- << "HT Capabilities=" << m_htCapability;
+ << "HT Capabilities=" << m_htCapability << " , "
+ << "VHT Capabilities= " << m_vhtCapability;
}
+
void
MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const
{
@@ -258,6 +290,7 @@
//i.WriteU8 (0, 3); //ds parameter set.
i = m_rates.extended.Serialize (i);
i = m_htCapability.Serialize (i);
+ i = m_vhtCapability.Serialize (i);
}
uint32_t
@@ -273,6 +306,7 @@
//i.Next (3); //ds parameter set
i = m_rates.extended.DeserializeIfPresent (i);
i = m_htCapability.DeserializeIfPresent (i);
+ i = m_vhtCapability.DeserializeIfPresent (i);
return i.GetDistanceFrom (start);
}
@@ -335,6 +369,18 @@
m_listenInterval = interval;
}
+void
+MgtAssocRequestHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities)
+{
+ m_vhtCapability = vhtcapabilities;
+}
+
+VhtCapabilities
+MgtAssocRequestHeader::GetVhtCapabilities (void) const
+{
+ return m_vhtCapability;
+}
+
HtCapabilities
MgtAssocRequestHeader::GetHtCapabilities (void) const
{
@@ -385,6 +431,7 @@
size += m_ssid.GetSerializedSize ();
size += m_rates.GetSerializedSize ();
size += m_htCapability.GetSerializedSize ();
+ size += m_vhtCapability.GetSerializedSize ();
size += m_rates.extended.GetSerializedSize ();
return size;
}
@@ -394,7 +441,8 @@
{
os << "ssid=" << m_ssid << ", "
<< "rates=" << m_rates << ", "
- << "HT Capabilities=" << m_htCapability;
+ << "HT Capabilities=" << m_htCapability << " , "
+ << "VHT Capabilities= " << m_vhtCapability;
}
void
@@ -407,6 +455,7 @@
i = m_rates.Serialize (i);
i = m_rates.extended.Serialize (i);
i = m_htCapability.Serialize (i);
+ i = m_vhtCapability.Serialize (i);
}
uint32_t
@@ -419,6 +468,7 @@
i = m_rates.Deserialize (i);
i = m_rates.extended.DeserializeIfPresent (i);
i = m_htCapability.DeserializeIfPresent (i);
+ i = m_vhtCapability.DeserializeIfPresent (i);
return i.GetDistanceFrom (start);
}
@@ -468,6 +518,18 @@
m_htCapability = htcapabilities;
}
+void
+MgtAssocResponseHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities)
+{
+ m_vhtCapability = vhtcapabilities;
+}
+
+VhtCapabilities
+MgtAssocResponseHeader::GetVhtCapabilities (void) const
+{
+ return m_vhtCapability;
+}
+
HtCapabilities
MgtAssocResponseHeader::GetHtCapabilities (void) const
{
@@ -501,6 +563,7 @@
size += m_rates.GetSerializedSize ();
size += m_rates.extended.GetSerializedSize ();
size += m_htCapability.GetSerializedSize ();
+ size += m_vhtCapability.GetSerializedSize ();
return size;
}
@@ -509,7 +572,8 @@
{
os << "status code=" << m_code << ", "
<< "rates=" << m_rates << ", "
- << "HT Capabilities=" << m_htCapability;
+ << "HT Capabilities=" << m_htCapability << " , "
+ << "VHT Capabilities= " << m_vhtCapability;
}
void
@@ -522,6 +586,7 @@
i = m_rates.Serialize (i);
i = m_rates.extended.Serialize (i);
i = m_htCapability.Serialize (i);
+ i = m_vhtCapability.Serialize (i);
}
uint32_t
@@ -534,6 +599,7 @@
i = m_rates.Deserialize (i);
i = m_rates.extended.DeserializeIfPresent (i);
i = m_htCapability.DeserializeIfPresent (i);
+ i = m_vhtCapability.DeserializeIfPresent (i);
return i.GetDistanceFrom (start);
}
@@ -609,7 +675,6 @@
{
ActionValue retval;
retval.selfProtectedAction = PEER_LINK_OPEN; //Needs to be initialized to something to quiet valgrind in default cases
-
switch (m_category)
{
case BLOCK_ACK:
@@ -626,6 +691,7 @@
break;
}
break;
+
case SELF_PROTECTED:
switch (m_actionValue)
{
@@ -735,10 +801,10 @@
{
if (value == BLOCK_ACK)
{
- return "BlockAck";
+ return "BlockAck";
}
else if (value == MESH)
- {
+ {
return "Mesh";
}
else if (value == SELF_PROTECTED)
@@ -790,7 +856,7 @@
void
WifiActionHeader::Print (std::ostream &os) const
{
- os << "category=" << CategoryValueToString ((CategoryValue) m_category)
+ os << "category=" << CategoryValueToString ((CategoryValue) m_category)
<< ", value=" << SelfProtectedActionValueToString ((SelfProtectedActionValue) m_actionValue);
}
--- a/src/wifi/model/mgt-headers.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/mgt-headers.h Thu Sep 03 22:16:49 2015 +0200
@@ -16,8 +16,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Mirko Banchi <mk.banchi@gmail.com>
*/
#ifndef MGT_HEADERS_H
@@ -31,6 +31,8 @@
#include "supported-rates.h"
#include "ssid.h"
#include "ht-capabilities.h"
+#include "ht-capabilities.h"
+#include "vht-capabilities.h"
namespace ns3 {
@@ -68,6 +70,18 @@
* \param htcapabilities HT capabilities
*/
void SetHtCapabilities (HtCapabilities htcapabilities);
+ /**
+ * Set the VHT capabilities.
+ *
+ * \param vhtcapabilities VHT capabilities
+ */
+ void SetVhtCapabilities (VhtCapabilities vhtcapabilities);
+ /**
+ * Return the VHT capabilities.
+ *
+ * \return VHT capabilities
+ */
+ VhtCapabilities GetVhtCapabilities (void) const;
/**
* Return the HT capabilities.
@@ -75,6 +89,7 @@
* \return HT capabilities
*/
HtCapabilities GetHtCapabilities (void) const;
+
/**
* Return the Service Set Identifier (SSID).
*
@@ -112,6 +127,7 @@
CapabilityInformation m_capability; //!< Capability information
HtCapabilities m_htCapability; //!< HT capabilities
uint16_t m_listenInterval;
+ VhtCapabilities m_vhtCapability; //!< VHT capabilities
};
@@ -143,7 +159,18 @@
* \return HT capabilities
*/
HtCapabilities GetHtCapabilities (void) const;
-
+ /**
+ * Set the VHT capabilities.
+ *
+ * \param vhtcapabilities VHT capabilities
+ */
+ void SetVhtCapabilities (VhtCapabilities vhtcapabilities);
+ /**
+ * Return the VHT capabilities.
+ *
+ * \return VHT capabilities
+ */
+ VhtCapabilities GetVhtCapabilities (void) const;
/**
* Set the HT capabilities.
*
@@ -174,13 +201,13 @@
virtual void Serialize (Buffer::Iterator start) const;
virtual uint32_t Deserialize (Buffer::Iterator start);
-
private:
- SupportedRates m_rates; //!< List of supported rates
+ SupportedRates m_rates; //!< List of supported rates
CapabilityInformation m_capability; //!< Capability information
- StatusCode m_code; //!< Status code
+ StatusCode m_code; //!< Status code
uint16_t m_aid;
- HtCapabilities m_htCapability; //!< HT capabilities
+ HtCapabilities m_htCapability; //!< HT capabilities
+ VhtCapabilities m_vhtCapability; //!< VHT capabilities
};
@@ -223,6 +250,18 @@
* \return HT capabilities
*/
HtCapabilities GetHtCapabilities (void) const;
+ /**
+ * Set the VHT capabilities.
+ *
+ * \param vhtcapabilities VHT capabilities
+ */
+ void SetVhtCapabilities (VhtCapabilities vhtcapabilities);
+ /**
+ * Return the VHT capabilities.
+ *
+ * \return VHT capabilities
+ */
+ VhtCapabilities GetVhtCapabilities (void) const;
/**
* Set the HT capabilities.
@@ -247,6 +286,7 @@
Ssid m_ssid; //!< Service Set ID (SSID)
SupportedRates m_rates; //!< List of supported rates
HtCapabilities m_htCapability; //!< HT capabilities
+ VhtCapabilities m_vhtCapability; //!< VHT capabilities
};
@@ -284,7 +324,18 @@
* \return HT capabilities
*/
HtCapabilities GetHtCapabilities (void) const;
-
+ /**
+ * Set the VHT capabilities.
+ *
+ * \param vhtcapabilities VHT capabilities
+ */
+ void SetVhtCapabilities (VhtCapabilities vhtcapabilities);
+ /**
+ * Return the VHT capabilities.
+ *
+ * \return VHT capabilities
+ */
+ VhtCapabilities GetVhtCapabilities (void) const;
/**
* Set the HT capabilities.
*
@@ -327,7 +378,6 @@
virtual void Serialize (Buffer::Iterator start) const;
virtual uint32_t Deserialize (Buffer::Iterator start);
-
private:
uint64_t m_timestamp; //!< Timestamp
Ssid m_ssid; //!< Service set ID (SSID)
@@ -335,6 +385,7 @@
SupportedRates m_rates; //!< List of supported rates
CapabilityInformation m_capability; //!< Capability information
HtCapabilities m_htCapability; //!< HT capabilities
+ VhtCapabilities m_vhtCapability; //!< VHT capabilities
};
--- a/src/wifi/model/minstrel-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/minstrel-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -474,6 +474,12 @@
uint32_t size)
{
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
if (!station->m_initialized)
{
CheckInit (station);
@@ -482,7 +488,7 @@
station->m_txrate = m_nsupported / 2;
}
UpdateStats (station);
- return WifiTxVector (GetSupported (station, station->m_txrate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ return WifiTxVector (GetSupported (station, station->m_txrate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
@@ -490,8 +496,13 @@
{
MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st;
NS_LOG_DEBUG ("DoGetRtsMode m_txrate=" << station->m_txrate);
-
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/mpdu-aggregator.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/mpdu-aggregator.h Thu Sep 03 22:16:49 2015 +0200
@@ -59,9 +59,13 @@
*/
virtual bool Aggregate (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket) = 0;
/**
+ * This method performs a VHT single MPDU aggregation.
+ */
+ virtual void AggregateVhtSingleMpdu (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket) = 0;
+ /**
* Adds A-MPDU subframe header and padding to each MPDU that is part of an A-MPDU before it is sent.
*/
- virtual void AddHeaderAndPad (Ptr<Packet> packet, bool last) = 0;
+ virtual void AddHeaderAndPad (Ptr<Packet> packet, bool last, bool vhtSingleMpdu) = 0;
/**
* \param packetSize size of the packet we want to insert into <i>aggregatedPacket</i>.
* \param aggregatedPacket packet that will contain the packet of size <i>packetSize</i>, if aggregation is possible.
--- a/src/wifi/model/mpdu-standard-aggregator.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/mpdu-standard-aggregator.cc Thu Sep 03 22:16:49 2015 +0200
@@ -82,15 +82,45 @@
}
void
-MpduStandardAggregator::AddHeaderAndPad (Ptr<Packet> packet, bool last)
+MpduStandardAggregator::AggregateVhtSingleMpdu (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket)
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Packet> currentPacket;
+ AmpduSubframeHeader currentHdr;
+
+ uint32_t padding = CalculatePadding (aggregatedPacket);
+ if (padding)
+ {
+ Ptr<Packet> pad = Create<Packet> (padding);
+ aggregatedPacket->AddAtEnd (pad);
+ }
+
+ currentHdr.SetEof (1);
+ currentHdr.SetCrc (1);
+ currentHdr.SetSig ();
+ currentHdr.SetLength (packet->GetSize ());
+ currentPacket = packet->Copy ();
+
+ currentPacket->AddHeader (currentHdr);
+ aggregatedPacket->AddAtEnd (currentPacket);
+}
+
+void
+MpduStandardAggregator::AddHeaderAndPad (Ptr<Packet> packet, bool last, bool vhtSingleMpdu)
{
NS_LOG_FUNCTION (this);
AmpduSubframeHeader currentHdr;
+
//This is called to prepare packets from the aggregate queue to be sent so no need to check total size since it has already been
//done before when deciding how many packets to add to the queue
currentHdr.SetCrc (1);
currentHdr.SetSig ();
currentHdr.SetLength (packet->GetSize ());
+ if (vhtSingleMpdu)
+ {
+ currentHdr.SetEof (1);
+ }
+
packet->AddHeader (currentHdr);
uint32_t padding = CalculatePadding (packet);
--- a/src/wifi/model/mpdu-standard-aggregator.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/mpdu-standard-aggregator.h Thu Sep 03 22:16:49 2015 +0200
@@ -48,9 +48,13 @@
*/
virtual bool Aggregate (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket);
/**
+ * This method performs a VHT single MPDU aggregation.
+ */
+ virtual void AggregateVhtSingleMpdu (Ptr<const Packet> packet, Ptr<Packet> aggregatedPacket);
+ /**
* Adds A-MPDU subframe header and padding to each MPDU that is part of an A-MPDU before it is sent.
*/
- virtual void AddHeaderAndPad (Ptr<Packet> packet, bool last);
+ virtual void AddHeaderAndPad (Ptr<Packet> packet, bool last, bool vhtSingleMpdu);
/**
* \param packetSize size of the packet we want to insert into <i>aggregatedPacket</i>.
* \param aggregatedPacket packet that will contain the packet of size <i>packetSize</i>, if aggregation is possible.
--- a/src/wifi/model/nist-error-rate-model.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/nist-error-rate-model.cc Thu Sep 03 22:16:49 2015 +0200
@@ -80,6 +80,14 @@
NS_LOG_INFO ("64-Qam" << " snr=" << snr << " ber=" << ber);
return ber;
}
+double
+NistErrorRateModel::Get256QamBer (double snr) const
+{
+ double z = std::sqrt (snr / (85.0 * 2.0));
+ double ber = 15.0 / 32.0 * 0.5 * erfc (z);
+ NS_LOG_INFO ("256-Qam" << " snr=" << snr << " ber=" << ber);
+ return ber;
+}
double
NistErrorRateModel::GetFecBpskBer (double snr, uint32_t nbits,
@@ -213,15 +221,31 @@
}
double
-NistErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
+NistErrorRateModel::GetFec256QamBer (double snr, uint32_t nbits,
+ uint32_t bValue) const
+{
+ double ber = Get256QamBer (snr);
+ if (ber == 0.0)
+ {
+ return 1.0;
+ }
+ double pe = CalculatePe (ber, bValue);
+ pe = std::min (pe, 1.0);
+ double pms = std::pow (1 - pe, static_cast<double> (nbits));
+ return pms;
+}
+
+double
+NistErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
{
if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
|| mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
- || mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
+ || mode.GetModulationClass () == WIFI_MOD_CLASS_HT
+ || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
{
- if (mode.GetConstellationSize () == 2)
+ if (mode.GetConstellationSize (1) == 2)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
{
return GetFecBpskBer (snr,
nbits,
@@ -234,9 +258,9 @@
3); //b value
}
}
- else if (mode.GetConstellationSize () == 4)
+ else if (mode.GetConstellationSize (1) == 4)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
{
return GetFecQpskBer (snr,
nbits,
@@ -249,9 +273,9 @@
3); //b value
}
}
- else if (mode.GetConstellationSize () == 16)
+ else if (mode.GetConstellationSize (1) == 16)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
{
return GetFec16QamBer (snr,
nbits,
@@ -264,15 +288,15 @@
3); //b value
}
}
- else if (mode.GetConstellationSize () == 64)
+ else if (mode.GetConstellationSize (1) == 64)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_2_3)
{
return GetFec64QamBer (snr,
nbits,
2); //b value
}
- else if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
+ else if (mode.GetCodeRate (1) == WIFI_CODE_RATE_5_6)
{
return GetFec64QamBer (snr,
nbits,
@@ -285,10 +309,27 @@
3); //b value
}
}
+ else if (mode.GetConstellationSize (1) == 256)
+ {
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_5_6)
+ {
+ return GetFec256QamBer (snr,
+ nbits,
+ 5 // b value
+ );
+ }
+ else
+ {
+ return GetFec256QamBer (snr,
+ nbits,
+ 3 // b value
+ );
+ }
+ }
}
- else if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS)
+ else if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS || mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)
{
- switch (mode.GetDataRate ())
+ switch (mode.GetDataRate (20, 0, 1))
{
case 1000000:
return DsssErrorRateModel::GetDsssDbpskSuccessRate (snr, nbits);
@@ -298,6 +339,8 @@
return DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (snr, nbits);
case 11000000:
return DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (snr, nbits);
+ default:
+ NS_ASSERT ("undefined DSSS/HR-DSSS datarate");
}
}
return 0;
--- a/src/wifi/model/nist-error-rate-model.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/nist-error-rate-model.h Thu Sep 03 22:16:49 2015 +0200
@@ -43,7 +43,7 @@
NistErrorRateModel ();
- virtual double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
+ virtual double GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const;
private:
@@ -89,6 +89,13 @@
*/
double Get64QamBer (double snr) const;
/**
+ * Return BER of QAM256 at the given SNR.
+ *
+ * \param snr snr value
+ * \return BER of QAM256 at the given SNR
+ */
+ double Get256QamBer (double snr) const;
+ /**
* Return BER of BPSK at the given SNR after applying FEC.
*
* \param snr snr value
@@ -132,6 +139,16 @@
*/
double GetFec64QamBer (double snr, uint32_t nbits,
uint32_t bValue) const;
+ /**
+ * Return BER of QAM256 at the given SNR after applying FEC.
+ *
+ * \param snr snr value
+ * \param nbits the number of bits in the chunk
+ * \param bValue
+ * \return BER of QAM256 at the given SNR after applying FEC
+ */
+ double GetFec256QamBer (double snr, uint32_t nbits,
+ uint32_t bValue) const;
};
} //namespace ns3
--- a/src/wifi/model/onoe-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/onoe-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -278,16 +278,28 @@
rateIndex = station->m_txrate;
}
}
- return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
OnoeWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
{
OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st;
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
UpdateMode (station);
/// \todo can we implement something smarter ?
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/parf-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/parf-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -294,8 +294,14 @@
{
NS_LOG_FUNCTION (this << st << size);
ParfWifiRemoteStation *station = (ParfWifiRemoteStation *) st;
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
CheckInit (station);
- return WifiTxVector (GetSupported (station, station->m_currentRate), station->m_currentPower, GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station));
+ return WifiTxVector (GetSupported (station, station->m_currentRate), station->m_currentPower, GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
@@ -305,7 +311,13 @@
/// \todo we could/should implement the Arf algorithm for
/// RTS only by picking a single rate within the BasicRateSet.
ParfWifiRemoteStation *station = (ParfWifiRemoteStation *) st;
- return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station));
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
--- a/src/wifi/model/regular-wifi-mac.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/regular-wifi-mac.cc Thu Sep 03 22:16:49 2015 +0200
@@ -119,6 +119,7 @@
NS_LOG_FUNCTION (this << stationManager);
m_stationManager = stationManager;
m_stationManager->SetHtSupported (GetHtSupported ());
+ m_stationManager->SetVhtSupported (GetVhtSupported ());
m_low->SetWifiRemoteStationManager (stationManager);
m_dca->SetWifiRemoteStationManager (stationManager);
@@ -262,6 +263,19 @@
}
bool
+RegularWifiMac::GetVhtSupported () const
+{
+ return m_vhtSupported;
+}
+
+void
+RegularWifiMac::SetVhtSupported (bool enable)
+{
+ NS_LOG_FUNCTION (this);
+ m_vhtSupported = enable;
+}
+
+bool
RegularWifiMac::GetHtSupported () const
{
return m_htSupported;
@@ -658,6 +672,12 @@
MakeBooleanAccessor (&RegularWifiMac::SetHtSupported,
&RegularWifiMac::GetHtSupported),
MakeBooleanChecker ())
+ .AddAttribute ("VhtSupported",
+ "This Boolean attribute is set to enable 802.11ac support at this STA",
+ BooleanValue (false),
+ MakeBooleanAccessor (&RegularWifiMac::SetVhtSupported,
+ &RegularWifiMac::GetVhtSupported),
+ MakeBooleanChecker ())
.AddAttribute ("CtsToSelfSupported",
"Use CTS to Self when using a rate that is not in the basic set rate",
BooleanValue (false),
@@ -715,6 +735,7 @@
case WIFI_PHY_STANDARD_80211_5MHZ:
case WIFI_PHY_STANDARD_80211n_5GHZ:
case WIFI_PHY_STANDARD_80211n_2_4GHZ:
+ case WIFI_PHY_STANDARD_80211ac:
cwmin = 15;
cwmax = 1023;
break;
--- a/src/wifi/model/regular-wifi-mac.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/regular-wifi-mac.h Thu Sep 03 22:16:49 2015 +0200
@@ -413,8 +413,7 @@
/**
* This Boolean is set \c true iff this WifiMac is to model
- * 802.11n. It is exposed through the
- * attribute system.
+ * 802.11n. It is exposed through the attribute system.
*
* At the moment, this flag is the sole selection between HT and
* non-HT operation for the STA (whether IBSS, AP, or
@@ -433,12 +432,30 @@
*/
void SetHtSupported (bool enable);
/**
- * Return whether the device supports QoS.
+ * Return whether the device supports HT.
*
* \return true if HT is supported, false otherwise
*/
bool GetHtSupported () const;
+ /**
+ * This Boolean is set \c true iff this WifiMac is to model
+ * 802.11ac. It is exposed through the attribute system.
+ */
+ bool m_vhtSupported;
+ /**
+ * Enable or disable HT support for the device.
+ *
+ * \param enable whether VHT is supported
+ */
+ void SetVhtSupported (bool enable);
+ /**
+ * Return whether the device supports VHT.
+ *
+ * \return true if VHT is supported, false otherwise
+ */
+ bool GetVhtSupported () const;
+
private:
RegularWifiMac (const RegularWifiMac &);
--- a/src/wifi/model/rraa-wifi-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/rraa-wifi-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -286,17 +286,30 @@
uint32_t size)
{
RraaWifiRemoteStation *station = (RraaWifiRemoteStation *) st;
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
if (!station->m_initialized)
{
ResetCountersBasic (station);
}
- return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station));
+ return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false);
}
WifiTxVector
RraaWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
{
- return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st));
+ RraaWifiRemoteStation *station = (RraaWifiRemoteStation *) st;
+ uint32_t channelWidth = GetChannelWidth (station);
+ if (channelWidth >= 40)
+ {
+ //avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
+ channelWidth = 20;
+ }
+ return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (st), false, 1, 0, channelWidth, GetAggregation (station), false);
}
bool
@@ -375,13 +388,13 @@
uint32_t rate) const
{
WifiMode mode = GetSupported (station, rate);
- return GetThresholds (mode);
+ return GetThresholds (mode, station);
}
struct RraaWifiManager::ThresholdsItem
-RraaWifiManager::GetThresholds (WifiMode mode) const
+RraaWifiManager::GetThresholds (WifiMode mode, RraaWifiRemoteStation *station) const
{
- switch (mode.GetDataRate () / 1000000)
+ switch (mode.GetDataRate (GetChannelWidth (station), GetShortGuardInterval (station), 1) / 1000000)
{
case 54:
{
--- a/src/wifi/model/rraa-wifi-manager.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/rraa-wifi-manager.h Thu Sep 03 22:16:49 2015 +0200
@@ -120,10 +120,11 @@
* Get a threshold for the given mode.
*
* \param mode
+ * \param station
*
* \return threshold
*/
- struct ThresholdsItem GetThresholds (WifiMode mode) const;
+ struct ThresholdsItem GetThresholds (WifiMode mode, RraaWifiRemoteStation *station) const;
/**
* Get a threshold for the given station and mode index.
*
--- a/src/wifi/model/sta-wifi-mac.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/sta-wifi-mac.cc Thu Sep 03 22:16:49 2015 +0200
@@ -37,6 +37,7 @@
#include "amsdu-subframe-header.h"
#include "mgt-headers.h"
#include "ht-capabilities.h"
+#include "vht-capabilities.h"
/*
* The state machine for this STA is:
@@ -181,12 +182,15 @@
MgtProbeRequestHeader probe;
probe.SetSsid (GetSsid ());
probe.SetSupportedRates (GetSupportedRates ());
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
probe.SetHtCapabilities (GetHtCapabilities ());
hdr.SetNoOrder ();
}
-
+ if (m_vhtSupported)
+ {
+ probe.SetVhtCapabilities (GetVhtCapabilities ());
+ }
packet->AddHeader (probe);
//The standard is not clear on the correct queue for management
@@ -218,12 +222,15 @@
MgtAssocRequestHeader assoc;
assoc.SetSsid (GetSsid ());
assoc.SetSupportedRates (GetSupportedRates ());
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
assoc.SetHtCapabilities (GetHtCapabilities ());
hdr.SetNoOrder ();
}
-
+ if (m_vhtSupported)
+ {
+ assoc.SetVhtCapabilities (GetVhtCapabilities ());
+ }
packet->AddHeader (assoc);
//The standard is not clear on the correct queue for management
@@ -391,7 +398,7 @@
{
hdr.SetTypeData ();
}
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
hdr.SetNoOrder ();
}
@@ -565,14 +572,24 @@
HtCapabilities htcapabilities = assocResp.GetHtCapabilities ();
m_stationManager->AddStationHtCapabilities (hdr->GetAddr2 (),htcapabilities);
}
+ if (m_vhtSupported)
+ {
+ VhtCapabilities vhtcapabilities = assocResp.GetVhtCapabilities ();
+ m_stationManager->AddStationVhtCapabilities (hdr->GetAddr2 (), vhtcapabilities);
+ }
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
- if (rates.IsSupportedRate (mode.GetDataRate ()))
+ uint32_t channelWidth = m_phy->GetChannelWidth ();
+ if (channelWidth > 20)
+ {
+ channelWidth = 20;
+ }
+ if (rates.IsSupportedRate (mode.GetDataRate (channelWidth, false, 1)))
{
m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
- if (rates.IsBasicRate (mode.GetDataRate ()))
+ if (rates.IsBasicRate (mode.GetDataRate (channelWidth, false, 1)))
{
m_stationManager->AddBasicMode (mode);
}
@@ -583,8 +600,21 @@
HtCapabilities htcapabilities = assocResp.GetHtCapabilities ();
for (uint32_t i = 0; i < m_phy->GetNMcs (); i++)
{
- uint8_t mcs = m_phy->GetMcs (i);
- if (htcapabilities.IsSupportedMcs (mcs))
+ WifiMode mcs = m_phy->GetMcs (i);
+ if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HT && htcapabilities.IsSupportedMcs (mcs.GetMcsValue ()))
+ {
+ m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
+ //here should add a control to add basic MCS when it is implemented
+ }
+ }
+ }
+ if (m_vhtSupported)
+ {
+ VhtCapabilities vhtcapabilities = assocResp.GetVhtCapabilities ();
+ for (uint32_t i = 0; i < m_phy->GetNMcs (); i++)
+ {
+ WifiMode mcs = m_phy->GetMcs (i);
+ if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VHT && vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
{
m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
//here should add a control to add basic MCS when it is implemented
@@ -615,7 +645,7 @@
StaWifiMac::GetSupportedRates (void) const
{
SupportedRates rates;
- if (m_htSupported)
+ if (m_htSupported || m_vhtSupported)
{
for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors (); i++)
{
@@ -625,7 +655,12 @@
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
WifiMode mode = m_phy->GetMode (i);
- rates.AddSupportedRate (mode.GetDataRate ());
+ uint32_t channelWidth = m_phy->GetChannelWidth ();
+ if (channelWidth > 20)
+ {
+ channelWidth = 20;
+ }
+ rates.AddSupportedRate (mode.GetDataRate (channelWidth, false, 1));
}
return rates;
}
@@ -635,26 +670,65 @@
{
HtCapabilities capabilities;
capabilities.SetHtSupported (1);
- capabilities.SetLdpc (m_phy->GetLdpc ());
- capabilities.SetSupportedChannelWidth (m_phy->GetChannelBonding ());
- capabilities.SetShortGuardInterval20 (m_phy->GetGuardInterval ());
- capabilities.SetShortGuardInterval40 (m_phy->GetChannelBonding () && m_phy->GetGuardInterval ());
- capabilities.SetGreenfield (m_phy->GetGreenfield ());
- capabilities.SetMaxAmsduLength (1); //hardcoded for now (TBD)
- capabilities.SetLSigProtectionSupport (!m_phy->GetGreenfield ());
- capabilities.SetMaxAmpduLength (3); //hardcoded for now (TBD)
- uint64_t maxSupportedRate = 0; //in bit/s
- for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
+ if (m_htSupported)
{
- capabilities.SetRxMcsBitmask (m_phy->GetMcs (i));
- if (((m_phy->McsToWifiMode (i)).GetDataRate ()) > maxSupportedRate)
+ capabilities.SetLdpc (m_phy->GetLdpc ());
+ capabilities.SetSupportedChannelWidth (m_phy->GetChannelWidth () == 40);
+ capabilities.SetShortGuardInterval20 (m_phy->GetGuardInterval ());
+ capabilities.SetShortGuardInterval40 (m_phy->GetChannelWidth () == 40 && m_phy->GetGuardInterval ());
+ capabilities.SetGreenfield (m_phy->GetGreenfield ());
+ capabilities.SetMaxAmsduLength (1); //hardcoded for now (TBD)
+ capabilities.SetLSigProtectionSupport (!m_phy->GetGreenfield ());
+ capabilities.SetMaxAmpduLength (3); //hardcoded for now (TBD)
+ uint64_t maxSupportedRate = 0; //in bit/s
+ for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
{
- maxSupportedRate = (m_phy->McsToWifiMode (i)).GetDataRate ();
+ WifiMode mcs = m_phy->GetMcs (i);
+ capabilities.SetRxMcsBitmask (mcs.GetMcsValue ());
+ if (mcs.GetDataRate (m_phy->GetGuardInterval (), m_phy->GetGuardInterval (), 1) > maxSupportedRate)
+ {
+ maxSupportedRate = mcs.GetDataRate (m_phy->GetGuardInterval (), m_phy->GetGuardInterval (), 1);
+ }
}
+ capabilities.SetRxHighestSupportedDataRate (maxSupportedRate / 1e6); //in Mbit/s
+ capabilities.SetTxMcsSetDefined (m_phy->GetNMcs () > 0);
+ capabilities.SetTxMaxNSpatialStreams (m_phy->GetNumberOfTransmitAntennas ());
}
- capabilities.SetRxHighestSupportedDataRate (maxSupportedRate / 1e6); //in Mbit/s
- capabilities.SetTxMcsSetDefined (m_phy->GetNMcs () > 0);
- capabilities.SetTxMaxNSpatialStreams (m_phy->GetNumberOfTransmitAntennas ());
+ return capabilities;
+}
+
+VhtCapabilities
+StaWifiMac::GetVhtCapabilities (void) const
+{
+ VhtCapabilities capabilities;
+ capabilities.SetVhtSupported (1);
+ if (m_vhtSupported)
+ {
+ if (m_phy->GetChannelWidth () == 160)
+ {
+ capabilities.SetSupportedChannelWidthSet (1);
+ }
+ else
+ {
+ capabilities.SetSupportedChannelWidthSet (0);
+ }
+ capabilities.SetMaxMpduLength (2); //hardcoded for now (TBD)
+ capabilities.SetRxLdpc (m_phy->GetLdpc ());
+ capabilities.SetShortGuardIntervalFor80Mhz ((m_phy->GetChannelWidth () == 80) && m_phy->GetGuardInterval ());
+ capabilities.SetShortGuardIntervalFor160Mhz ((m_phy->GetChannelWidth () == 160) && m_phy->GetGuardInterval ());
+ capabilities.SetMaxAmpduLengthExponent (7); //hardcoded for now (TBD)
+ uint8_t maxMcs = 0;
+ for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
+ {
+ WifiMode mcs = m_phy->GetMcs (i);
+ if (mcs.GetMcsValue () > maxMcs)
+ {
+ maxMcs = mcs.GetMcsValue ();
+ }
+ }
+ capabilities.SetRxMcsMap (maxMcs, 1); //Only 1 SS is currently supported
+ capabilities.SetTxMcsMap (maxMcs, 1); //Only 1 SS is currently supported
+ }
return capabilities;
}
--- a/src/wifi/model/sta-wifi-mac.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/sta-wifi-mac.h Thu Sep 03 22:16:49 2015 +0200
@@ -176,6 +176,12 @@
* \return the HT capability that we support
*/
HtCapabilities GetHtCapabilities (void) const;
+ /**
+ * Return the VHT capability of the current AP.
+ *
+ * \return the VHT capability that we support
+ */
+ VhtCapabilities GetVhtCapabilities (void) const;
enum MacState m_state;
Time m_probeRequestTimeout;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/model/vht-capabilities.cc Thu Sep 03 22:16:49 2015 +0200
@@ -0,0 +1,473 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2015
+ *
+ * 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: Ghada Badawy <gbadawy@rim.com>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
+ */
+
+#include "vht-capabilities.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("VhtCapabilities");
+
+namespace ns3 {
+
+VhtCapabilities::VhtCapabilities ()
+ : m_maxMpduLength (0),
+ m_supportedChannelWidthSet (0),
+ m_rxLdpc (0),
+ m_shortGuardIntervalFor80Mhz (0),
+ m_shortGuardIntervalFor160Mhz (0),
+ m_txStbc (0),
+ m_rxStbc (0),
+ m_suBeamformerCapable (0),
+ m_suBeamformeeCapable (0),
+ m_beamformeeStsCapable (0),
+ m_numberOfSoundingDimensions (0),
+ m_muBeamformerCapable (0),
+ m_muBeamformeeCapable (0),
+ m_vhtTxopPs (0),
+ m_htcVhtCapable (0),
+ m_maxAmpduLengthExponent (0),
+ m_vhtLinkAdaptationCapable (0),
+ m_rxAntennaPatternConsistency (0),
+ m_txAntennaPatternConsistency (0),
+ m_rxHighestSupportedLongGuardIntervalDataRate (0),
+ m_txHighestSupportedLongGuardIntervalDataRate (0),
+ m_vhtSupported (0)
+{
+ m_rxMcsMap.resize (8,0);
+ m_txMcsMap.resize (8,0);
+}
+
+WifiInformationElementId
+VhtCapabilities::ElementId () const
+{
+ return IE_VHT_CAPABILITIES;
+}
+
+void
+VhtCapabilities::SetVhtSupported (uint8_t vhtsupported)
+{
+ m_vhtSupported = vhtsupported;
+}
+
+uint8_t
+VhtCapabilities::GetInformationFieldSize () const
+{
+ //we should not be here if ht is not supported
+ NS_ASSERT (m_vhtSupported > 0);
+ return 12;
+}
+
+Buffer::Iterator
+VhtCapabilities::Serialize (Buffer::Iterator i) const
+{
+ if (m_vhtSupported < 1)
+ {
+ return i;
+ }
+ return WifiInformationElement::Serialize (i);
+}
+
+uint16_t
+VhtCapabilities::GetSerializedSize () const
+{
+ if (m_vhtSupported < 1)
+ {
+ return 0;
+ }
+ return WifiInformationElement::GetSerializedSize ();
+}
+
+void
+VhtCapabilities::SerializeInformationField (Buffer::Iterator start) const
+{
+ if (m_vhtSupported == 1)
+ {
+ //write the corresponding value for each bit
+ start.WriteHtolsbU32 (GetVhtCapabilitiesInfo ());
+ start.WriteHtolsbU64 (GetSupportedMcsAndNssSet ());
+ }
+}
+
+uint8_t
+VhtCapabilities::DeserializeInformationField (Buffer::Iterator start,
+ uint8_t length)
+{
+ Buffer::Iterator i = start;
+ uint16_t vhtinfo = i.ReadLsbtohU32 ();
+ uint64_t mcsset = i.ReadLsbtohU64 ();
+ SetVhtCapabilitiesInfo (vhtinfo);
+ SetSupportedMcsAndNssSet (mcsset);
+ return length;
+}
+
+void
+VhtCapabilities::SetVhtCapabilitiesInfo (uint32_t ctrl)
+{
+ m_maxMpduLength = ctrl & 0x03;
+ m_supportedChannelWidthSet = (ctrl >> 2) & 0x03;
+ m_rxLdpc = (ctrl >> 4) & 0x01;
+ m_shortGuardIntervalFor80Mhz = (ctrl >> 5) & 0x01;
+ m_shortGuardIntervalFor160Mhz = (ctrl >> 6) & 0x01;
+ m_txStbc = (ctrl >> 7) & 0x01;
+ m_rxStbc = (ctrl >> 8) & 0x07;
+ m_suBeamformerCapable = (ctrl >> 11) & 0x01;
+ m_suBeamformeeCapable = (ctrl >> 12) & 0x01;
+ m_beamformeeStsCapable = (ctrl >> 13) & 0x07;
+ m_numberOfSoundingDimensions = (ctrl >> 16) & 0x07;
+ m_muBeamformerCapable = (ctrl >> 19) & 0x01;
+ m_muBeamformeeCapable = (ctrl >> 20) & 0x01;
+ m_vhtTxopPs = (ctrl >> 21) & 0x01;
+ m_htcVhtCapable = (ctrl >> 22) & 0x01;
+ m_maxAmpduLengthExponent = (ctrl >> 23) & 0x07;
+ m_vhtLinkAdaptationCapable = (ctrl >> 26) & 0x03;
+ m_rxAntennaPatternConsistency = (ctrl >> 28) & 0x01;
+ m_txAntennaPatternConsistency = (ctrl >> 29) & 0x01;
+}
+
+uint32_t
+VhtCapabilities::GetVhtCapabilitiesInfo () const
+{
+ uint32_t val = 0;
+ val |= m_maxMpduLength & 0x03;
+ val |= (m_supportedChannelWidthSet & 0x03) << 2;
+ val |= (m_rxLdpc & 0x01) << 4;
+ val |= (m_shortGuardIntervalFor80Mhz & 0x01) << 5;
+ val |= (m_shortGuardIntervalFor160Mhz & 0x01) << 6;
+ val |= (m_txStbc & 0x01) << 7;
+ val |= (m_rxStbc & 0x07) << 8;
+ val |= (m_suBeamformerCapable & 0x01) << 11;
+ val |= (m_suBeamformeeCapable & 0x01) << 12;
+ val |= (m_beamformeeStsCapable & 0x07) << 13;
+ val |= (m_numberOfSoundingDimensions & 0x07) << 16;
+ val |= (m_muBeamformerCapable & 0x01) << 19;
+ val |= (m_muBeamformeeCapable & 0x01) << 20;
+ val |= (m_vhtTxopPs & 0x01) << 21;
+ val |= (m_htcVhtCapable & 0x01) << 22;
+ val |= (m_maxAmpduLengthExponent & 0x07) << 23;
+ val |= (m_vhtLinkAdaptationCapable & 0x03) << 26;
+ val |= (m_rxAntennaPatternConsistency & 0x01) << 28;
+ val |= (m_txAntennaPatternConsistency & 0x01) << 29;
+ return val;
+}
+
+void
+VhtCapabilities::SetSupportedMcsAndNssSet (uint64_t ctrl)
+{
+ uint16_t n;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ n = i * 2;
+ m_rxMcsMap[i] = (ctrl >> n) & 0x03;
+ }
+ m_rxHighestSupportedLongGuardIntervalDataRate = (ctrl >> 16) & 0x1fff;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ uint16_t n = (i * 2) + 32;
+ m_txMcsMap[i] = (ctrl >> n) & 0x03;
+ }
+ m_txHighestSupportedLongGuardIntervalDataRate = (ctrl >> 48) & 0x1fff;
+}
+
+uint64_t
+VhtCapabilities::GetSupportedMcsAndNssSet () const
+{
+ uint64_t val = 0;
+ uint16_t n;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ n = i * 2;
+ val |= ((uint64_t)m_rxMcsMap[i] & 0x03) << n;
+ }
+ val |= ((uint64_t)m_rxHighestSupportedLongGuardIntervalDataRate & 0x1fff) << 16;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ n = (i * 2) + 32;
+ val |= ((uint64_t)m_txMcsMap[i] & 0x03) << n;
+ }
+ val |= ((uint64_t)m_txHighestSupportedLongGuardIntervalDataRate & 0x1fff) << 48;
+ return val;
+}
+
+void
+VhtCapabilities::SetMaxMpduLength (uint8_t length)
+{
+ m_maxMpduLength = length;
+}
+
+void
+VhtCapabilities::SetSupportedChannelWidthSet (uint8_t channelwidthset)
+{
+ m_supportedChannelWidthSet = channelwidthset;
+}
+
+void
+VhtCapabilities::SetRxLdpc (uint8_t rxldpc)
+{
+ m_rxLdpc = rxldpc;
+}
+
+void
+VhtCapabilities::SetShortGuardIntervalFor80Mhz (uint8_t shortguardinterval)
+{
+ m_shortGuardIntervalFor80Mhz = shortguardinterval;
+}
+
+void
+VhtCapabilities::SetShortGuardIntervalFor160Mhz (uint8_t shortguardinterval)
+{
+ m_shortGuardIntervalFor160Mhz = shortguardinterval;
+}
+
+void
+VhtCapabilities::SetRxStbc (uint8_t rxstbc)
+{
+ m_rxStbc = rxstbc;
+}
+
+void
+VhtCapabilities::SetTxStbc (uint8_t txstbc)
+{
+ m_txStbc = txstbc;
+}
+
+void
+VhtCapabilities::SetMaxAmpduLengthExponent (uint8_t exponent)
+{
+ m_maxAmpduLengthExponent = exponent;
+}
+
+void
+VhtCapabilities::SetRxMcsMap (uint16_t map)
+{
+ //Set each element in the map accoriding to the 2 bits representing it page 98 in the 11ac standard
+ uint8_t n;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ n = i * 2;
+ m_rxMcsMap[i] = (map >> n) & 0x03;
+ }
+}
+
+void
+VhtCapabilities::SetRxMcsMap (uint8_t mcs, uint8_t nss)
+{
+ //MCS index should be at least 7 and should not exceed 9
+ NS_ASSERT (mcs >= 7 && mcs <= 9);
+ m_rxMcsMap[nss - 1] = mcs - 7; //1 = MCS 8; 2 = MCS 9
+}
+
+void
+VhtCapabilities::SetTxMcsMap (uint16_t map)
+{
+ //Set each element in the map accoriding to the 2 bits representing it page 98 in the 11ac standard
+ uint8_t n;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ n = i * 2;
+ m_txMcsMap[i] = (map >> n) & 0x03;
+ }
+}
+
+void
+VhtCapabilities::SetTxMcsMap (uint8_t mcs, uint8_t nss)
+{
+ //MCS index should be at least 7 and should not exceed 9
+ NS_ASSERT (mcs >= 7 && mcs <= 9);
+ m_txMcsMap[nss - 1] = mcs - 7; //1 = MCS 8; 2 = MCS 9
+}
+
+bool
+VhtCapabilities::IsSupportedTxMcs (uint8_t mcs) const
+{
+ NS_ASSERT (mcs >= 0 && mcs <= 9);
+ if (mcs <= 7)
+ {
+ return true;
+ }
+ if (mcs == 8 && m_txMcsMap[0] == 1)
+ {
+ return true;
+ }
+ if (mcs == 9 && m_txMcsMap[0] == 2)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool
+VhtCapabilities::IsSupportedRxMcs (uint8_t mcs) const
+{
+ NS_ASSERT (mcs >= 0 && mcs <= 9);
+ if (mcs <= 7)
+ {
+ return true;
+ }
+ if (mcs == 8 && m_rxMcsMap[0] == 1)
+ {
+ return true;
+ }
+ if (mcs == 9 && m_rxMcsMap[0] == 2)
+ {
+ return true;
+ }
+ return false;
+}
+
+void
+VhtCapabilities::SetRxHighestSupportedLgiDataRate (uint16_t supporteddatarate)
+{
+ m_rxHighestSupportedLongGuardIntervalDataRate = supporteddatarate;
+}
+
+void
+VhtCapabilities::SetTxHighestSupportedLgiDataRate (uint16_t supporteddatarate)
+{
+ m_txHighestSupportedLongGuardIntervalDataRate = supporteddatarate;
+}
+
+uint8_t
+VhtCapabilities::GetMaxMpduLength () const
+{
+ return m_maxMpduLength;
+}
+
+uint8_t
+VhtCapabilities::GetSupportedChannelWidthSet () const
+{
+ return m_supportedChannelWidthSet;
+}
+
+uint8_t
+VhtCapabilities::GetRxLdpc () const
+{
+ return m_rxLdpc;
+}
+
+uint8_t
+VhtCapabilities::GetShortGuardIntervalFor80Mhz () const
+{
+ return m_shortGuardIntervalFor80Mhz;
+}
+
+uint8_t
+VhtCapabilities::GetShortGuardIntervalFor160Mhz () const
+{
+ return m_shortGuardIntervalFor160Mhz;
+}
+
+uint8_t
+VhtCapabilities::GetRxStbc () const
+{
+ return m_rxStbc;
+}
+
+uint8_t
+VhtCapabilities::GetTxStbc () const
+{
+ return m_txStbc;
+}
+
+uint8_t
+VhtCapabilities::GetMaxAmpduLengthExponent () const
+{
+ return m_maxAmpduLengthExponent;
+}
+
+bool
+VhtCapabilities::IsSupportedMcs (uint8_t mcs, uint8_t nss) const
+{
+ //The MCS index starts at 0 and NSS starts at 1
+ if (mcs <= 7 && m_rxMcsMap[nss - 1] < 3)
+ {
+ return true;
+ }
+ if (mcs == 8 && m_rxMcsMap[nss - 1] > 0 && m_rxMcsMap[nss - 1] < 3)
+ {
+ return true;
+ }
+ if (mcs == 9 && m_rxMcsMap[nss - 1] == 2)
+ {
+ return true;
+ }
+ return false;
+}
+
+uint16_t
+VhtCapabilities::GetRxMcsMap () const
+{
+ uint16_t val = 0;
+ uint8_t n;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ n = i * 2;
+ val |= (m_rxMcsMap[i] & 0x03) << n;
+ }
+ return val;
+}
+
+uint16_t
+VhtCapabilities::GetTxMcsMap () const
+{
+ uint16_t val = 0;
+ uint8_t n;
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ n = i * 2;
+ val |= (m_txMcsMap[i] & 0x03) << n;
+ }
+ return val;
+}
+
+uint16_t
+VhtCapabilities::GetRxHighestSupportedLgiDataRate () const
+{
+ return m_rxHighestSupportedLongGuardIntervalDataRate;
+}
+
+uint16_t
+VhtCapabilities::GetTxHighestSupportedLgiDataRate () const
+{
+ return m_txHighestSupportedLongGuardIntervalDataRate;
+}
+
+ATTRIBUTE_HELPER_CPP (VhtCapabilities);
+
+std::ostream &
+operator << (std::ostream &os, const VhtCapabilities &VhtCapabilities)
+{
+ os << VhtCapabilities.GetVhtCapabilitiesInfo () << "|" << VhtCapabilities.GetSupportedMcsAndNssSet ();
+
+ return os;
+}
+
+std::istream &operator >> (std::istream &is,VhtCapabilities &VhtCapabilities)
+{
+ uint32_t c1;
+ uint64_t c2;
+ is >> c1 >> c2;
+ VhtCapabilities.SetVhtCapabilitiesInfo (c1);
+ VhtCapabilities.SetSupportedMcsAndNssSet (c2);
+
+ return is;
+}
+
+} //namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/model/vht-capabilities.h Thu Sep 03 22:16:49 2015 +0200
@@ -0,0 +1,159 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2015
+ *
+ * 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: Ghada Badawy <gbadawy@gmail.com>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
+ */
+
+#ifndef VHT_CAPABILITIES_H
+#define VHT_CAPABILITIES_H
+
+#include <stdint.h>
+#include "ns3/buffer.h"
+#include "ns3/attribute-helper.h"
+#include "ns3/wifi-information-element.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup wifi
+ *
+ * The IEEE 802.11ac VHT Capabilities
+ */
+class VhtCapabilities : public WifiInformationElement
+{
+public:
+ VhtCapabilities ();
+ void SetVhtSupported (uint8_t vhtsupported);
+
+ WifiInformationElementId ElementId () const;
+ uint8_t GetInformationFieldSize () const;
+ void SerializeInformationField (Buffer::Iterator start) const;
+ uint8_t DeserializeInformationField (Buffer::Iterator start, uint8_t length);
+
+ /**
+ * Set the VHT Capabilties Info field in the VHT Capabilities information element.
+ *
+ * \param ctrl the VHT Capabilties Info field in the VHT Capabilities information element
+ */
+ void SetVhtCapabilitiesInfo (uint32_t ctrl);
+ /**
+ * Set the MCS and NSS field in the VHT Capabilities information element.
+ *
+ * \param ctrl the MCS and NSS field in the VHT Capabilities information element
+ */
+ void SetSupportedMcsAndNssSet (uint64_t ctrl);
+
+ /*
+ * Return the VHT Capabilties Info field in the VHT Capabilities information element.
+ *
+ * \return the VHT Capabilties Info field in the VHT Capabilities information element
+ */
+ uint32_t GetVhtCapabilitiesInfo () const;
+ /*
+ * Return the MCS and NSS field in the VHT Capabilities information element.
+ *
+ * \return the MCS and NSS field in the VHT Capabilities information element
+ */
+ uint64_t GetSupportedMcsAndNssSet () const;
+
+ //Capabilities Info fields
+ void SetMaxMpduLength (uint8_t length);
+ void SetSupportedChannelWidthSet (uint8_t channelwidthset);
+ void SetRxLdpc (uint8_t rxldpc);
+ void SetShortGuardIntervalFor80Mhz (uint8_t shortguardinterval);
+ void SetShortGuardIntervalFor160Mhz (uint8_t shortguardinterval);
+ void SetRxStbc (uint8_t rxstbc);
+ void SetTxStbc (uint8_t txstbc);
+ void SetMaxAmpduLengthExponent (uint8_t exponent);
+
+ uint8_t GetMaxMpduLength () const;
+ uint8_t GetSupportedChannelWidthSet () const;
+ uint8_t GetRxLdpc () const;
+ uint8_t GetShortGuardIntervalFor80Mhz () const;
+ uint8_t GetShortGuardIntervalFor160Mhz () const;
+ uint8_t GetRxStbc () const;
+ uint8_t GetTxStbc () const;
+ uint8_t GetMaxAmpduLengthExponent () const;
+
+ //MCS and NSS field information
+ void SetRxMcsMap (uint16_t map);
+ void SetRxMcsMap (uint8_t mcs, uint8_t nss);
+ void SetTxMcsMap (uint16_t map);
+ void SetTxMcsMap (uint8_t mcs, uint8_t nss);
+ void SetRxHighestSupportedLgiDataRate (uint16_t supporteddatarate);
+ void SetTxHighestSupportedLgiDataRate (uint16_t supporteddatarate);
+ bool IsSupportedMcs (uint8_t mcs, uint8_t Nss) const;
+
+ uint16_t GetRxMcsMap () const;
+ uint16_t GetTxMcsMap () const;
+ uint16_t GetRxHighestSupportedLgiDataRate () const;
+ uint16_t GetTxHighestSupportedLgiDataRate () const;
+
+ bool IsSupportedTxMcs (uint8_t mcs) const;
+ bool IsSupportedRxMcs (uint8_t mcs) const;
+
+ /*
+ * This information element is a bit special in that it is only
+ * included if the STA is an VHT STA. To support this we
+ * override the Serialize and GetSerializedSize methods of
+ * WifiInformationElement.
+ */
+ Buffer::Iterator Serialize (Buffer::Iterator start) const;
+ uint16_t GetSerializedSize () const;
+
+
+private:
+ //Capabilities Info fields
+ uint16_t m_maxMpduLength;
+ uint16_t m_supportedChannelWidthSet;
+ uint8_t m_rxLdpc;
+ uint8_t m_shortGuardIntervalFor80Mhz;
+ uint8_t m_shortGuardIntervalFor160Mhz;
+ uint8_t m_txStbc;
+ uint8_t m_rxStbc;
+ uint8_t m_suBeamformerCapable;
+ uint8_t m_suBeamformeeCapable;
+ uint8_t m_beamformeeStsCapable;
+ uint8_t m_numberOfSoundingDimensions;
+ uint8_t m_muBeamformerCapable;
+ uint8_t m_muBeamformeeCapable;
+ uint8_t m_vhtTxopPs;
+ uint8_t m_htcVhtCapable;
+ uint8_t m_maxAmpduLengthExponent;
+ uint8_t m_vhtLinkAdaptationCapable;
+ uint8_t m_rxAntennaPatternConsistency;
+ uint8_t m_txAntennaPatternConsistency;
+
+ //MCS and NSS field information
+ std::vector<uint8_t> m_rxMcsMap;
+ uint16_t m_rxHighestSupportedLongGuardIntervalDataRate;
+ std::vector<uint8_t> m_txMcsMap;
+ uint16_t m_txHighestSupportedLongGuardIntervalDataRate;
+
+ //This is used to decide if this element should be added to the frame or not
+ uint8_t m_vhtSupported;
+};
+
+std::ostream &operator << (std::ostream &os, const VhtCapabilities &vhtcapabilities);
+std::istream &operator >> (std::istream &is, VhtCapabilities &vhtcapabilities);
+
+ATTRIBUTE_HELPER_HEADER (VhtCapabilities)
+
+} //namespace ns3
+
+#endif /* VHT_CAPABILITY_H */
--- a/src/wifi/model/wifi-information-element.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-information-element.h Thu Sep 03 22:16:49 2015 +0200
@@ -85,7 +85,8 @@
#define IE_EXTENDED_SUPPORTED_RATES ((WifiInformationElementId)50)
// 51 to 126 are reserved in 802.11-2007
#define IE_EXTENDED_CAPABILITIES ((WifiInformationElementId)127)
-// 128 to 220 are reserved in 802.11-2007
+// 128 to 190 are reserved in 802.11-2007
+#define IE_VHT_CAPABILITIES ((WifiInformationElementId)191)
#define IE_VENDOR_SPECIFIC ((WifiInformationElementId)221)
// 222 to 255 are reserved in 802.11-2007
#define IE11S_LINK_METRIC_REPORT ((WifiInformationElementId)115)
--- a/src/wifi/model/wifi-mac.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-mac.cc Thu Sep 03 22:16:49 2015 +0200
@@ -314,6 +314,9 @@
case WIFI_PHY_STANDARD_80211n_5GHZ:
Configure80211n_5Ghz ();
break;
+ case WIFI_PHY_STANDARD_80211ac:
+ Configure80211ac ();
+ break;
default:
NS_ASSERT (false);
break;
@@ -395,6 +398,12 @@
}
void
+WifiMac::Configure80211ac (void)
+{
+ Configure80211n_5Ghz ();
+}
+
+void
WifiMac::ConfigureDcf (Ptr<Dcf> dcf, uint32_t cwmin, uint32_t cwmax, enum AcIndex ac)
{
/* see IEE802.11 section 7.3.2.29 */
--- a/src/wifi/model/wifi-mac.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-mac.h Thu Sep 03 22:16:49 2015 +0200
@@ -290,6 +290,7 @@
* \sa WifiMac::Configure80211_5Mhz
* \sa WifiMac::Configure80211n_2_4Ghz
* \sa WifiMac::Configure80211n_5Ghz
+ * \sa WifiMac::Configure80211ac
*/
void ConfigureStandard (enum WifiPhyStandard standard);
@@ -421,15 +422,20 @@
void Configure80211_5Mhz ();
/**
* This method sets 802.11n 2.4 GHz standards-compliant defaults for following attributes:
- * Sifs, Slot, EifsNoDifs, Pifs, CtsTimeout, and AckTimeout.
+ * Sifs, Rifs, Slot, EifsNoDifs, Pifs, CtsTimeout, and AckTimeout.
* There is no support for short slot time.
*/
void Configure80211n_2_4Ghz (void);
/**
* This method sets 802.11n 5 GHz standards-compliant defaults for following attributes:
- * Sifs, Slot, EifsNoDifs, Pifs, CtsTimeout, and AckTimeout.
+ * Sifs, Rifs, Slot, EifsNoDifs, Pifs, CtsTimeout, and AckTimeout.
*/
void Configure80211n_5Ghz (void);
+ /**
+ * This method sets 802.11ac standards-compliant defaults for following attributes:
+ * Sifs, Slot, EifsNoDifs, Pifs, CtsTimeout, and AckTimeout.
+ */
+ void Configure80211ac (void);
/**
* The trace source fired when packets come into the "top" of the device
--- a/src/wifi/model/wifi-mode.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-mode.cc Thu Sep 03 22:16:49 2015 +0200
@@ -15,13 +15,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include "wifi-mode.h"
#include "ns3/simulator.h"
#include "ns3/assert.h"
#include "ns3/log.h"
+#include <cmath>
namespace ns3 {
@@ -67,39 +69,269 @@
return is;
}
-uint32_t
-WifiMode::GetBandwidth (void) const
+uint64_t
+WifiMode::GetPhyRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
{
- struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
- return item->bandwidth;
-}
-
-uint64_t
-WifiMode::GetPhyRate (void) const
-{
- struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
- return item->phyRate;
+ uint32_t dataRate, phyRate;
+ dataRate = GetDataRate (channelWidth, isShortGuardInterval, nss);
+ switch (GetCodeRate (nss))
+ {
+ case WIFI_CODE_RATE_5_6:
+ phyRate = dataRate * 6 / 5;
+ break;
+ case WIFI_CODE_RATE_3_4:
+ phyRate = dataRate * 4 / 3;
+ break;
+ case WIFI_CODE_RATE_2_3:
+ phyRate = dataRate * 3 / 2;
+ break;
+ case WIFI_CODE_RATE_1_2:
+ phyRate = dataRate * 2 / 1;
+ break;
+ case WIFI_CODE_RATE_UNDEFINED:
+ default:
+ phyRate = dataRate;
+ break;
+ }
+ return phyRate;
}
uint64_t
-WifiMode::GetDataRate (void) const
+WifiMode::GetDataRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
{
struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
- return item->dataRate;
+ uint64_t dataRate = 0;
+ if (nss > 1)
+ {
+ NS_FATAL_ERROR ("MIMO is not supported");
+ return 0;
+ }
+ if (item->modClass == WIFI_MOD_CLASS_DSSS)
+ {
+ dataRate = (11000000 / 11) * log2 (GetConstellationSize (1));
+ }
+ else if (item->modClass == WIFI_MOD_CLASS_HR_DSSS)
+ {
+ dataRate = (11000000 / 8) * log2 (GetConstellationSize (1));
+ }
+ else if (item->modClass == WIFI_MOD_CLASS_OFDM || item->modClass == WIFI_MOD_CLASS_ERP_OFDM)
+ {
+ double symbolRate = (1 / 4.0) * 1e6;
+
+ uint32_t usableSubCarriers;
+ switch (channelWidth)
+ {
+ case 20:
+ default:
+ usableSubCarriers = 48;
+ break;
+ case 10:
+ usableSubCarriers = 24;
+ break;
+ case 5:
+ usableSubCarriers = 12;
+ break;
+ }
+
+ double codingRate;
+ switch (GetCodeRate (1))
+ {
+ case WIFI_CODE_RATE_3_4:
+ codingRate = (3.0 / 4.0);
+ break;
+ case WIFI_CODE_RATE_2_3:
+ codingRate = (2.0 / 3.0);
+ break;
+ case WIFI_CODE_RATE_1_2:
+ codingRate = (1.0 / 2.0);
+ break;
+ case WIFI_CODE_RATE_UNDEFINED:
+ default:
+ NS_FATAL_ERROR ("trying to get datarate for a mcs without any coding rate defined");
+ break;
+ }
+
+ uint32_t numberOfBitsPerSubcarrier = log2 (GetConstellationSize (1));
+
+ dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
+ }
+ else if (item->modClass == WIFI_MOD_CLASS_HT || item->modClass == WIFI_MOD_CLASS_VHT)
+ {
+ if (item->mcsValue == 9)
+ {
+ //VHT MCS 9 forbidden at 20 MHz
+ NS_ASSERT (channelWidth != 20);
+ }
+
+ double symbolRate;
+ if (!isShortGuardInterval)
+ {
+ symbolRate = (1 / 4.0) * 1e6;
+ }
+ else
+ {
+ symbolRate = (1 / 3.6) * 1e6;
+ }
+
+ uint32_t usableSubCarriers;
+ switch (channelWidth)
+ {
+ case 20:
+ default:
+ usableSubCarriers = 52;
+ break;
+ case 40:
+ usableSubCarriers = 108;
+ break;
+ case 80:
+ usableSubCarriers = 234;
+ break;
+ case 160:
+ usableSubCarriers = 468;
+ break;
+ }
+
+ double codingRate;
+ switch (GetCodeRate (nss))
+ {
+ case WIFI_CODE_RATE_5_6:
+ codingRate = (5.0 / 6.0);
+ break;
+ case WIFI_CODE_RATE_3_4:
+ codingRate = (3.0 / 4.0);
+ break;
+ case WIFI_CODE_RATE_2_3:
+ codingRate = (2.0 / 3.0);
+ break;
+ case WIFI_CODE_RATE_1_2:
+ codingRate = (1.0 / 2.0);
+ break;
+ case WIFI_CODE_RATE_UNDEFINED:
+ default:
+ NS_FATAL_ERROR ("trying to get datarate for a mcs without any coding rate defined");
+ break;
+ }
+
+ uint32_t numberOfBitsPerSubcarrier = log2 (GetConstellationSize (nss));
+
+ dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
+ }
+ else
+ {
+ NS_ASSERT ("undefined datarate for the modulation class!");
+ }
+ return dataRate;
}
enum WifiCodeRate
-WifiMode::GetCodeRate (void) const
+WifiMode::GetCodeRate (uint8_t nss) const
{
struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
- return item->codingRate;
+ if (item->modClass == WIFI_MOD_CLASS_HT)
+ {
+ NS_ASSERT (nss <= 4);
+ NS_ASSERT ((item->mcsValue - (8 * (nss - 1))) >= 0 || (item->mcsValue - (8 * (nss - 1))) <= 7);
+ switch (item->mcsValue - (8 * (nss - 1)))
+ {
+ case 0:
+ case 1:
+ case 3:
+ return WIFI_CODE_RATE_1_2;
+ case 2:
+ case 4:
+ case 6:
+ return WIFI_CODE_RATE_3_4;
+ case 5:
+ return WIFI_CODE_RATE_2_3;
+ case 7:
+ return WIFI_CODE_RATE_5_6;
+ default:
+ return WIFI_CODE_RATE_UNDEFINED;
+ }
+ }
+ else if (item->modClass == WIFI_MOD_CLASS_VHT)
+ {
+ NS_ASSERT (nss <= 8);
+ switch (item->mcsValue)
+ {
+ case 0:
+ case 1:
+ case 3:
+ return WIFI_CODE_RATE_1_2;
+ case 2:
+ case 4:
+ case 6:
+ case 8:
+ return WIFI_CODE_RATE_3_4;
+ case 5:
+ return WIFI_CODE_RATE_2_3;
+ case 7:
+ case 9:
+ return WIFI_CODE_RATE_5_6;
+ default:
+ return WIFI_CODE_RATE_UNDEFINED;
+ }
+ }
+ else
+ {
+ return item->codingRate;
+ }
}
-uint8_t
-WifiMode::GetConstellationSize (void) const
+uint16_t
+WifiMode::GetConstellationSize (uint8_t nss) const
{
struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
- return item->constellationSize;
+ if (item->modClass == WIFI_MOD_CLASS_HT)
+ {
+ NS_ASSERT (nss <= 4);
+ NS_ASSERT ((item->mcsValue - (8 * (nss - 1))) >= 0 || (item->mcsValue - (8 * (nss - 1))) <= 7);
+ switch (item->mcsValue - (8 * (nss - 1)))
+ {
+ case 0:
+ return 2;
+ case 1:
+ case 2:
+ return 4;
+ case 3:
+ case 4:
+ return 16;
+ case 5:
+ case 6:
+ case 7:
+ return 64;
+ default:
+ return 0;
+ }
+ }
+ else if (item->modClass == WIFI_MOD_CLASS_VHT)
+ {
+ NS_ASSERT (nss <= 8);
+ switch (item->mcsValue)
+ {
+ case 0:
+ return 2;
+ case 1:
+ case 2:
+ return 4;
+ case 3:
+ case 4:
+ return 16;
+ case 5:
+ case 6:
+ case 7:
+ return 64;
+ case 8:
+ case 9:
+ return 256;
+ default:
+ return 0;
+ }
+ }
+ else
+ {
+ return item->constellationSize;
+ }
}
std::string
@@ -117,6 +349,22 @@
return item->isMandatory;
}
+uint8_t
+WifiMode::GetMcsValue (void) const
+{
+ struct WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
+ if (item->modClass == WIFI_MOD_CLASS_HT || item->modClass == WIFI_MOD_CLASS_VHT)
+ {
+ return item->mcsValue;
+ }
+ else
+ {
+ //We should not go here!
+ NS_ASSERT (false);
+ return 0;
+ }
+}
+
uint32_t
WifiMode::GetUid (void) const
{
@@ -134,6 +382,7 @@
: m_uid (0)
{
}
+
WifiMode::WifiMode (uint32_t uid)
: m_uid (uid)
{
@@ -154,10 +403,8 @@
WifiModeFactory::CreateWifiMode (std::string uniqueName,
enum WifiModulationClass modClass,
bool isMandatory,
- uint32_t bandwidth,
- uint32_t dataRate,
enum WifiCodeRate codingRate,
- uint8_t constellationSize)
+ uint16_t constellationSize)
{
WifiModeFactory *factory = GetFactory ();
uint32_t uid = factory->AllocateUid (uniqueName);
@@ -166,45 +413,50 @@
item->modClass = modClass;
//The modulation class for this WifiMode must be valid.
NS_ASSERT (modClass != WIFI_MOD_CLASS_UNKNOWN);
- item->bandwidth = bandwidth;
- item->dataRate = dataRate;
item->codingRate = codingRate;
- switch (codingRate)
- {
- case WIFI_CODE_RATE_5_6:
- item->phyRate = dataRate * 6 / 5;
- break;
- case WIFI_CODE_RATE_3_4:
- item->phyRate = dataRate * 4 / 3;
- break;
- case WIFI_CODE_RATE_2_3:
- item->phyRate = dataRate * 3 / 2;
- break;
- case WIFI_CODE_RATE_1_2:
- item->phyRate = dataRate * 2 / 1;
- break;
- case WIFI_CODE_RATE_UNDEFINED:
- default:
- item->phyRate = dataRate;
- break;
- }
-
//Check for compatibility between modulation class and coding
//rate. If modulation class is DSSS then coding rate must be
//undefined, and vice versa. I could have done this with an
//assertion, but it seems better to always give the error (i.e.,
//not only in non-optimised builds) and the cycles that extra test
//here costs are only suffered at simulation setup.
- if ((codingRate == WIFI_CODE_RATE_UNDEFINED) != (modClass == WIFI_MOD_CLASS_DSSS))
+ if ((codingRate == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS && modClass != WIFI_MOD_CLASS_HR_DSSS)
{
NS_FATAL_ERROR ("Error in creation of WifiMode named " << uniqueName << std::endl
- << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is WIFI_MOD_CLASS_DSSS");
+ << "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
}
item->constellationSize = constellationSize;
item->isMandatory = isMandatory;
+ NS_ASSERT (modClass != WIFI_MOD_CLASS_HT && modClass != WIFI_MOD_CLASS_VHT);
+ //fill unused mcs item with a dummy value
+ item->mcsValue = 0;
+
+ return WifiMode (uid);
+}
+
+WifiMode
+WifiModeFactory::CreateWifiMcs (std::string uniqueName,
+ uint8_t mcsValue,
+ enum WifiModulationClass modClass)
+{
+ WifiModeFactory *factory = GetFactory ();
+ uint32_t uid = factory->AllocateUid (uniqueName);
+ WifiModeItem *item = factory->Get (uid);
+ item->uniqueUid = uniqueName;
+ item->modClass = modClass;
+
+ //The modulation class must be either HT or VHT
+ NS_ASSERT (modClass == WIFI_MOD_CLASS_HT || modClass == WIFI_MOD_CLASS_VHT);
+
+ item->mcsValue = mcsValue;
+ //fill unused items with dummy values
+ item->constellationSize = 0;
+ item->codingRate = WIFI_CODE_RATE_UNDEFINED;
+ item->isMandatory = false;
+
return WifiMode (uid);
}
@@ -278,13 +530,11 @@
uint32_t uid = factory.AllocateUid ("Invalid-WifiMode");
WifiModeItem *item = factory.Get (uid);
item->uniqueUid = "Invalid-WifiMode";
- item->bandwidth = 0;
- item->dataRate = 0;
- item->phyRate = 0;
item->modClass = WIFI_MOD_CLASS_UNKNOWN;
item->constellationSize = 0;
item->codingRate = WIFI_CODE_RATE_UNDEFINED;
item->isMandatory = false;
+ item->mcsValue = 0;
isFirstTime = false;
}
return &factory;
--- a/src/wifi/model/wifi-mode.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-mode.h Thu Sep 03 22:16:49 2015 +0200
@@ -15,7 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#ifndef WIFI_MODE_H
@@ -43,8 +44,10 @@
WIFI_MOD_CLASS_IR,
/** Frequency-hopping spread spectrum (FHSS) PHY (Clause 14) */
WIFI_MOD_CLASS_FHSS,
- /** DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18) */
+ /** DSSS PHY (Clause 15) */
WIFI_MOD_CLASS_DSSS,
+ /** HR/DSSS PHY (Clause 18) */
+ WIFI_MOD_CLASS_HR_DSSS,
/** ERP-PBCC PHY (19.6) */
WIFI_MOD_CLASS_ERP_PBCC,
/** DSSS-OFDM PHY (19.7) */
@@ -54,7 +57,9 @@
/** OFDM PHY (Clause 17) */
WIFI_MOD_CLASS_OFDM,
/** HT PHY (Clause 20) */
- WIFI_MOD_CLASS_HT
+ WIFI_MOD_CLASS_HT,
+ /** VHT PHY (Clause 22) */
+ WIFI_MOD_CLASS_VHT
};
/**
@@ -76,7 +81,6 @@
WIFI_CODE_RATE_1_2,
/** Rate 5/6 */
WIFI_CODE_RATE_5_6
-
};
/**
@@ -94,28 +98,44 @@
{
public:
/**
- * \returns the number of Hz used by this signal
- */
- uint32_t GetBandwidth (void) const;
- /**
+ *
+ * \param channelWidth the considered channel width in MHz
+ * \param isShortGuardInterval whether short guard interval is considered or not
+ * \param nss the considered number of streams
+ *
* \returns the physical bit rate of this signal.
*
* If a transmission mode uses 1/2 FEC, and if its
- * data rate is 3Mbps, the phy rate is 6Mbps
+ * data rate is 3.25Mbps, the phy rate is 6.5Mbps
*/
- uint64_t GetPhyRate (void) const;
+ uint64_t GetPhyRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const;
/**
+ *
+ * \param channelWidth the considered channel width in MHz
+ * \param isShortGuardInterval whether short guard interval is considered or not
+ * \param nss the considered number of streams
+ *
* \returns the data bit rate of this signal.
*/
- uint64_t GetDataRate (void) const;
+ uint64_t GetDataRate (uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const;
/**
+ *
+ * \param nss the considered number of streams
+ *
* \returns the coding rate of this transmission mode
*/
- enum WifiCodeRate GetCodeRate (void) const;
+ enum WifiCodeRate GetCodeRate (uint8_t nss) const;
/**
+ *
+ * \param nss the considered number of streams
+ *
* \returns the size of the modulation constellation.
*/
- uint8_t GetConstellationSize (void) const;
+ uint16_t GetConstellationSize (uint8_t nss) const;
+ /**
+ * \returns the MCS value.
+ */
+ uint8_t GetMcsValue (void) const;
/**
* \returns a human-readable representation of this WifiMode
* instance.
@@ -187,15 +207,6 @@
typedef WifiModeList::const_iterator WifiModeListIterator;
/**
- * A list of Wi-Fi Modulation and Coding Scheme (MCS).
- */
-typedef std::vector<uint8_t> WifiMcsList;
-/**
- * An iterator for WifiMcsList vector.
- */
-typedef WifiMcsList::const_iterator WifiMcsListIterator;
-
-/**
* \brief create WifiMode class instances and keep track of them.
*
* This factory ensures that each WifiMode created has a unique name
@@ -209,9 +220,6 @@
* must be unique accross _all_ instances.
* \param modClass the class of modulation
* \param isMandatory true if this WifiMode is mandatory, false otherwise.
- * \param bandwidth the bandwidth (Hz) of the signal generated when the
- * associated WifiMode is used.
- * \param dataRate the rate (bits/second) at which the user data is transmitted
* \param codingRate if convolutional coding is used for this rate
* then this parameter specifies the convolutional coding rate
* used. If there is no explicit convolutional coding step (e.g.,
@@ -221,15 +229,27 @@
*
* \return WifiMode
*
- * Create a WifiMode.
+ * Create a WifiMode (not used for HT or VHT).
*/
static WifiMode CreateWifiMode (std::string uniqueName,
enum WifiModulationClass modClass,
bool isMandatory,
- uint32_t bandwidth,
- uint32_t dataRate,
enum WifiCodeRate codingRate,
- uint8_t constellationSize);
+ uint16_t constellationSize);
+
+ /**
+ * \param uniqueName the name of the associated WifiMode. This name
+ * must be unique accross _all_ instances.
+ * \param mcsValue the mcs value
+ * \param modClass the class of modulation
+ *
+ * \return WifiMode
+ *
+ * Create a HT or VHT WifiMode.
+ */
+ static WifiMode CreateWifiMcs (std::string uniqueName,
+ uint8_t mcsValue,
+ enum WifiModulationClass modClass);
private:
@@ -252,13 +272,11 @@
struct WifiModeItem
{
std::string uniqueUid;
- uint32_t bandwidth;
- uint32_t dataRate;
- uint32_t phyRate;
enum WifiModulationClass modClass;
- uint8_t constellationSize;
+ uint16_t constellationSize;
enum WifiCodeRate codingRate;
bool isMandatory;
+ uint8_t mcsValue;
};
/**
@@ -296,4 +314,3 @@
} //namespace ns3
#endif /* WIFI_MODE_H */
-
--- a/src/wifi/model/wifi-phy-standard.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-phy-standard.h Thu Sep 03 22:16:49 2015 +0200
@@ -17,12 +17,12 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
+
#ifndef WIFI_PHY_STANDARD_H
#define WIFI_PHY_STANDARD_H
namespace ns3 {
-
/**
* \ingroup wifi
* Identifies the PHY specification that a Wifi device is configured to use.
@@ -48,7 +48,9 @@
/** HT OFDM PHY for the 2.4 GHz band (clause 20) */
WIFI_PHY_STANDARD_80211n_2_4GHZ,
/** HT OFDM PHY for the 5 GHz band (clause 20) */
- WIFI_PHY_STANDARD_80211n_5GHZ
+ WIFI_PHY_STANDARD_80211n_5GHZ,
+ /** VHT OFDM PHY (clause 22) */
+ WIFI_PHY_STANDARD_80211ac
};
} //namespace ns3
--- a/src/wifi/model/wifi-phy.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-phy.cc Thu Sep 03 22:16:49 2015 +0200
@@ -15,7 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include "wifi-phy.h"
@@ -118,16 +119,15 @@
}
WifiMode
-WifiPhy::GetHTPlcpHeaderMode (WifiMode payloadMode)
+WifiPhy::GetHtPlcpHeaderMode (WifiMode payloadMode)
{
- switch (payloadMode.GetBandwidth ())
- {
- case 20000000:
- default:
- return WifiPhy::GetOfdmRate6_5MbpsBW20MHz ();
- case 40000000:
- return WifiPhy::GetOfdmRate13_5MbpsBW40MHz ();
- }
+ return WifiPhy::GetHtMcs0 ();
+}
+
+WifiMode
+WifiPhy::GetVhtPlcpHeaderMode (WifiMode payloadMode)
+{
+ return WifiPhy::GetVhtMcs0 ();
}
Time
@@ -140,10 +140,19 @@
{
Ndltf = txVector.GetNss ();
}
- else
+ else if (txVector.GetNss () < 5)
{
Ndltf = 4;
}
+ else if (txVector.GetNss () < 7)
+ {
+ Ndltf = 6;
+ }
+ else
+ {
+ Ndltf = 8;
+ }
+
if (txVector.GetNess () < 3)
{
Neltf = txVector.GetNess ();
@@ -159,6 +168,8 @@
return MicroSeconds (4 + (4 * Ndltf) + (4 * Neltf));
case WIFI_PREAMBLE_HT_GF:
return MicroSeconds ((4 * Ndltf) + (4 * Neltf));
+ case WIFI_PREAMBLE_VHT:
+ return MicroSeconds (4 + (4 * Ndltf));
default:
//no training for non HT
return MicroSeconds (0);
@@ -180,31 +191,77 @@
}
}
+Time
+WifiPhy::GetPlcpVhtSigA1Duration (WifiPreamble preamble)
+{
+ switch (preamble)
+ {
+ case WIFI_PREAMBLE_VHT:
+ //VHT-SIG-A1
+ return MicroSeconds (4);
+ default:
+ // no VHT-SIG-A1 for non VHT
+ return MicroSeconds (0);
+ }
+}
+
+Time
+WifiPhy::GetPlcpVhtSigA2Duration (WifiPreamble preamble)
+{
+ switch (preamble)
+ {
+ case WIFI_PREAMBLE_VHT:
+ //VHT-SIG-A2
+ return MicroSeconds (4);
+ default:
+ // no VHT-SIG-A2 for non VHT
+ return MicroSeconds (0);
+ }
+}
+
+Time
+WifiPhy::GetPlcpVhtSigBDuration (WifiPreamble preamble)
+{
+ switch (preamble)
+ {
+ case WIFI_PREAMBLE_VHT:
+ //VHT-SIG-B
+ return MicroSeconds (4);
+ default:
+ // no VHT-SIG-B for non VHT
+ return MicroSeconds (0);
+ }
+}
+
WifiMode
-WifiPhy::GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
+WifiPhy::GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble, WifiTxVector txVector)
{
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
case WIFI_MOD_CLASS_HT:
- {
- switch (payloadMode.GetBandwidth ())
- {
- case 5000000:
- return WifiPhy::GetOfdmRate1_5MbpsBW5MHz ();
- case 10000000:
- return WifiPhy::GetOfdmRate3MbpsBW10MHz ();
- default:
- //(Section 18.3.2 "PLCP frame format"; IEEE Std 802.11-2012)
- //actually this is only the first part of the PlcpHeader,
- //because the last 16 bits of the PlcpHeader are using the
- //same mode of the payload
- return WifiPhy::GetOfdmRate6Mbps ();
- }
- }
+ case WIFI_MOD_CLASS_VHT:
+ switch (txVector.GetChannelWidth ())
+ {
+ case 5000000:
+ return WifiPhy::GetOfdmRate1_5MbpsBW5MHz ();
+ case 10000000:
+ return WifiPhy::GetOfdmRate3MbpsBW10MHz ();
+ case 20000000:
+ case 40000000:
+ case 80000000:
+ case 160000000:
+ default:
+ //(Section 18.3.2 "PLCP frame format"; IEEE Std 802.11-2012)
+ //actually this is only the first part of the PlcpHeader,
+ //because the last 16 bits of the PlcpHeader are using the
+ //same mode of the payload
+ return WifiPhy::GetOfdmRate6Mbps ();
+ }
case WIFI_MOD_CLASS_ERP_OFDM:
return WifiPhy::GetErpOfdmRate6Mbps ();
case WIFI_MOD_CLASS_DSSS:
+ case WIFI_MOD_CLASS_HR_DSSS:
if (preamble == WIFI_PREAMBLE_LONG)
{
//(Section 16.2.3 "PLCP field definitions" and Section 17.2.2.2 "Long PPDU format"; IEEE Std 802.11-2012)
@@ -222,17 +279,17 @@
}
Time
-WifiPhy::GetPlcpHeaderDuration (WifiMode payloadMode, WifiPreamble preamble)
+WifiPhy::GetPlcpHeaderDuration (WifiTxVector txVector, WifiPreamble preamble)
{
if (preamble == WIFI_PREAMBLE_NONE)
{
return MicroSeconds (0);
}
- switch (payloadMode.GetModulationClass ())
+ switch (txVector.GetMode ().GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
- switch (payloadMode.GetBandwidth ())
+ switch (txVector.GetChannelWidth ())
{
case 20000000:
default:
@@ -264,9 +321,11 @@
return MicroSeconds (0);
}
}
+ case WIFI_MOD_CLASS_VHT:
case WIFI_MOD_CLASS_ERP_OFDM:
return MicroSeconds (4);
case WIFI_MOD_CLASS_DSSS:
+ case WIFI_MOD_CLASS_HR_DSSS:
if (preamble == WIFI_PREAMBLE_SHORT)
{
//(Section 17.2.2.3 "Short PPDU format" and Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012)
@@ -284,17 +343,17 @@
}
Time
-WifiPhy::GetPlcpPreambleDuration (WifiMode payloadMode, WifiPreamble preamble)
+WifiPhy::GetPlcpPreambleDuration (WifiTxVector txVector, WifiPreamble preamble)
{
if (preamble == WIFI_PREAMBLE_NONE)
{
return MicroSeconds (0);
}
- switch (payloadMode.GetModulationClass ())
+ switch (txVector.GetMode ().GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
- switch (payloadMode.GetBandwidth ())
+ switch (txVector.GetChannelWidth ())
{
case 20000000:
default:
@@ -311,18 +370,20 @@
return MicroSeconds (64);
}
}
+ case WIFI_MOD_CLASS_VHT:
case WIFI_MOD_CLASS_HT:
//IEEE 802.11n Figure 20.1 the training symbols before L_SIG or HT_SIG
return MicroSeconds (16);
case WIFI_MOD_CLASS_ERP_OFDM:
return MicroSeconds (16);
case WIFI_MOD_CLASS_DSSS:
+ case WIFI_MOD_CLASS_HR_DSSS:
if (preamble == WIFI_PREAMBLE_SHORT)
{
//(Section 17.2.2.3 "Short PPDU format)" Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012)
return MicroSeconds (72);
}
- else //WIFI_PREAMBLE_LONG
+ else //WIFI_PREAMBLE_LONG
{
//(Section 17.2.2.2 "Long PPDU format)" Figure 17-1 "Long PPDU format"; IEEE Std 802.11-2012)
return MicroSeconds (144);
@@ -347,7 +408,8 @@
//(Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012
//corresponds to T_{SYM} in the table)
Time symbolDuration;
- switch (payloadMode.GetBandwidth ())
+
+ switch (txVector.GetChannelWidth ())
{
case 20000000:
default:
@@ -363,8 +425,7 @@
//(Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012)
//corresponds to N_{DBPS} in the table
- double numDataBitsPerSymbol = payloadMode.GetDataRate () * symbolDuration.GetNanoSeconds () / 1e9;
-
+ double numDataBitsPerSymbol = payloadMode.GetDataRate (20, 0, 1) * symbolDuration.GetNanoSeconds () / 1e9;
//(Section 18.3.5.4 "Pad bits (PAD)" Equation 18-11; IEEE Std 802.11-2012)
uint32_t numSymbols;
@@ -421,39 +482,19 @@
}
}
case WIFI_MOD_CLASS_HT:
+ case WIFI_MOD_CLASS_VHT:
{
Time symbolDuration;
double m_Stbc;
//if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
//In the future has to create a stationmanager that only uses these data rates if sender and reciever support GI
- if (payloadMode.GetUniqueName () == "OfdmRate135MbpsBW40MHzShGi" || payloadMode.GetUniqueName () == "OfdmRate65MbpsBW20MHzShGi" )
+ if (txVector.IsShortGuardInterval ())
{
symbolDuration = NanoSeconds (3600);
}
else
{
- switch (payloadMode.GetDataRate () / (txVector.GetNss ()))
- {
- //shortGi
- case 7200000:
- case 14400000:
- case 21700000:
- case 28900000:
- case 43300000:
- case 57800000:
- case 72200000:
- case 15000000:
- case 30000000:
- case 45000000:
- case 60000000:
- case 90000000:
- case 120000000:
- case 150000000:
- symbolDuration = NanoSeconds (3600);
- break;
- default:
- symbolDuration = MicroSeconds (4);
- }
+ symbolDuration = MicroSeconds (4);
}
if (txVector.IsStbc ())
@@ -465,12 +506,22 @@
m_Stbc = 1;
}
- //check tables 20-35 and 20-36 in the standard to get cases when nes =2
- double Nes = 1;
+ //check tables 20-35 and 20-36 in the .11n standard to get cases when nes = 2
+ //check tables 22-30 to 22-61 in the .11ac standard to get cases when nes > 1
+ double Nes;
+ if (txVector.GetChannelWidth () == 160
+ && (payloadMode.GetUniqueName () == "VhtMcs7" || payloadMode.GetUniqueName () == "VhtMcs8" || payloadMode.GetUniqueName () == "VhtMcs9"))
+ {
+ Nes = 2;
+ }
+ else
+ {
+ Nes = 1;
+ }
//IEEE Std 802.11n, section 20.3.11, equation (20-32)
uint32_t numSymbols;
- double numDataBitsPerSymbol = payloadMode.GetDataRate () * txVector.GetNss () * symbolDuration.GetNanoSeconds () / 1e9;
+ double numDataBitsPerSymbol = payloadMode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1) * txVector.GetNss () * symbolDuration.GetNanoSeconds () / 1e9;
if (packetType == 1 && preamble != WIFI_PREAMBLE_NONE)
{
@@ -515,7 +566,7 @@
NS_FATAL_ERROR ("Wrong combination of preamble and packet type");
}
- if (frequency >= 2400 && frequency <= 2500 && ((packetType == 0 && preamble != WIFI_PREAMBLE_NONE) || (packetType == 2 && preamble == WIFI_PREAMBLE_NONE))) //at 2.4 GHz
+ if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT && frequency >= 2400 && frequency <= 2500 && ((packetType == 0 && preamble != WIFI_PREAMBLE_NONE) || (packetType == 2 && preamble == WIFI_PREAMBLE_NONE))) //at 2.4 GHz
{
return Time (numSymbols * symbolDuration) + MicroSeconds (6);
}
@@ -525,11 +576,12 @@
}
}
case WIFI_MOD_CLASS_DSSS:
+ case WIFI_MOD_CLASS_HR_DSSS:
//(Section 17.2.3.6 "Long PLCP LENGTH field"; IEEE Std 802.11-2012)
NS_LOG_LOGIC (" size=" << size
<< " mode=" << payloadMode
- << " rate=" << payloadMode.GetDataRate ());
- return MicroSeconds (lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate () / 1.0e6))));
+ << " rate=" << payloadMode.GetDataRate (20, 0, 1));
+ return MicroSeconds (lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate (20, 0, 1) / 1.0e6))));
default:
NS_FATAL_ERROR ("unsupported modulation class");
return MicroSeconds (0);
@@ -539,11 +591,13 @@
Time
WifiPhy::CalculatePlcpPreambleAndHeaderDuration (WifiTxVector txVector, WifiPreamble preamble)
{
- WifiMode payloadMode = txVector.GetMode ();
- Time duration = GetPlcpPreambleDuration (payloadMode, preamble)
- + GetPlcpHeaderDuration (payloadMode, preamble)
+ Time duration = GetPlcpPreambleDuration (txVector, preamble)
+ + GetPlcpHeaderDuration (txVector, preamble)
+ GetPlcpHtSigHeaderDuration (preamble)
- + GetPlcpHtTrainingSymbolDuration (preamble, txVector);
+ + GetPlcpVhtSigA1Duration (preamble)
+ + GetPlcpVhtSigA2Duration (preamble)
+ + GetPlcpHtTrainingSymbolDuration (preamble, txVector)
+ + GetPlcpVhtSigBDuration (preamble);
return duration;
}
@@ -613,7 +667,6 @@
WifiModeFactory::CreateWifiMode ("DsssRate1Mbps",
WIFI_MOD_CLASS_DSSS,
true,
- 22000000, 1000000,
WIFI_CODE_RATE_UNDEFINED,
2);
return mode;
@@ -626,7 +679,6 @@
WifiModeFactory::CreateWifiMode ("DsssRate2Mbps",
WIFI_MOD_CLASS_DSSS,
true,
- 22000000, 2000000,
WIFI_CODE_RATE_UNDEFINED,
4);
return mode;
@@ -640,11 +692,10 @@
{
static WifiMode mode =
WifiModeFactory::CreateWifiMode ("DsssRate5_5Mbps",
- WIFI_MOD_CLASS_DSSS,
+ WIFI_MOD_CLASS_HR_DSSS,
true,
- 22000000, 5500000,
WIFI_CODE_RATE_UNDEFINED,
- 4);
+ 16);
return mode;
}
@@ -653,11 +704,10 @@
{
static WifiMode mode =
WifiModeFactory::CreateWifiMode ("DsssRate11Mbps",
- WIFI_MOD_CLASS_DSSS,
+ WIFI_MOD_CLASS_HR_DSSS,
true,
- 22000000, 11000000,
WIFI_CODE_RATE_UNDEFINED,
- 4);
+ 256);
return mode;
}
@@ -671,7 +721,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate6Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
true,
- 20000000, 6000000,
WIFI_CODE_RATE_1_2,
2);
return mode;
@@ -684,7 +733,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate9Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
false,
- 20000000, 9000000,
WIFI_CODE_RATE_3_4,
2);
return mode;
@@ -697,7 +745,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate12Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
true,
- 20000000, 12000000,
WIFI_CODE_RATE_1_2,
4);
return mode;
@@ -710,7 +757,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate18Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
false,
- 20000000, 18000000,
WIFI_CODE_RATE_3_4,
4);
return mode;
@@ -723,7 +769,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate24Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
true,
- 20000000, 24000000,
WIFI_CODE_RATE_1_2,
16);
return mode;
@@ -736,7 +781,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate36Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
false,
- 20000000, 36000000,
WIFI_CODE_RATE_3_4,
16);
return mode;
@@ -749,7 +793,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate48Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
false,
- 20000000, 48000000,
WIFI_CODE_RATE_2_3,
64);
return mode;
@@ -762,7 +805,6 @@
WifiModeFactory::CreateWifiMode ("ErpOfdmRate54Mbps",
WIFI_MOD_CLASS_ERP_OFDM,
false,
- 20000000, 54000000,
WIFI_CODE_RATE_3_4,
64);
return mode;
@@ -778,7 +820,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate6Mbps",
WIFI_MOD_CLASS_OFDM,
true,
- 20000000, 6000000,
WIFI_CODE_RATE_1_2,
2);
return mode;
@@ -791,7 +832,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate9Mbps",
WIFI_MOD_CLASS_OFDM,
false,
- 20000000, 9000000,
WIFI_CODE_RATE_3_4,
2);
return mode;
@@ -804,7 +844,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate12Mbps",
WIFI_MOD_CLASS_OFDM,
true,
- 20000000, 12000000,
WIFI_CODE_RATE_1_2,
4);
return mode;
@@ -817,7 +856,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate18Mbps",
WIFI_MOD_CLASS_OFDM,
false,
- 20000000, 18000000,
WIFI_CODE_RATE_3_4,
4);
return mode;
@@ -830,7 +868,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate24Mbps",
WIFI_MOD_CLASS_OFDM,
true,
- 20000000, 24000000,
WIFI_CODE_RATE_1_2,
16);
return mode;
@@ -843,7 +880,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate36Mbps",
WIFI_MOD_CLASS_OFDM,
false,
- 20000000, 36000000,
WIFI_CODE_RATE_3_4,
16);
return mode;
@@ -856,7 +892,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate48Mbps",
WIFI_MOD_CLASS_OFDM,
false,
- 20000000, 48000000,
WIFI_CODE_RATE_2_3,
64);
return mode;
@@ -869,7 +904,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate54Mbps",
WIFI_MOD_CLASS_OFDM,
false,
- 20000000, 54000000,
WIFI_CODE_RATE_3_4,
64);
return mode;
@@ -885,7 +919,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
true,
- 10000000, 3000000,
WIFI_CODE_RATE_1_2,
2);
return mode;
@@ -898,7 +931,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 10000000, 4500000,
WIFI_CODE_RATE_3_4,
2);
return mode;
@@ -911,7 +943,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
true,
- 10000000, 6000000,
WIFI_CODE_RATE_1_2,
4);
return mode;
@@ -924,7 +955,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 10000000, 9000000,
WIFI_CODE_RATE_3_4,
4);
return mode;
@@ -937,7 +967,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
true,
- 10000000, 12000000,
WIFI_CODE_RATE_1_2,
16);
return mode;
@@ -950,7 +979,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate18MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 10000000, 18000000,
WIFI_CODE_RATE_3_4,
16);
return mode;
@@ -963,7 +991,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate24MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 10000000, 24000000,
WIFI_CODE_RATE_2_3,
64);
return mode;
@@ -976,7 +1003,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW10MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 10000000, 27000000,
WIFI_CODE_RATE_3_4,
64);
return mode;
@@ -992,7 +1018,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate1_5MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
true,
- 5000000, 1500000,
WIFI_CODE_RATE_1_2,
2);
return mode;
@@ -1005,7 +1030,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate2_25MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 5000000, 2250000,
WIFI_CODE_RATE_3_4,
2);
return mode;
@@ -1018,7 +1042,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
true,
- 5000000, 3000000,
WIFI_CODE_RATE_1_2,
4);
return mode;
@@ -1031,7 +1054,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 5000000, 4500000,
WIFI_CODE_RATE_3_4,
4);
return mode;
@@ -1044,7 +1066,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
true,
- 5000000, 6000000,
WIFI_CODE_RATE_1_2,
16);
return mode;
@@ -1057,7 +1078,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 5000000, 9000000,
WIFI_CODE_RATE_3_4,
16);
return mode;
@@ -1070,7 +1090,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 5000000, 12000000,
WIFI_CODE_RATE_2_3,
64);
return mode;
@@ -1083,7 +1102,6 @@
WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW5MHz",
WIFI_MOD_CLASS_OFDM,
false,
- 5000000, 13500000,
WIFI_CODE_RATE_3_4,
64);
return mode;
@@ -1093,421 +1111,343 @@
// Clause 20
WifiMode
-WifiPhy::GetOfdmRate6_5MbpsBW20MHz ()
+WifiPhy::GetHtMcs0 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate6_5MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 6500000,
- WIFI_CODE_RATE_1_2,
- 2);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs0", 0, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate7_2MbpsBW20MHz ()
+WifiPhy::GetHtMcs1 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate7_2MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 7200000,
- WIFI_CODE_RATE_1_2,
- 2);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs1", 1, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate13MbpsBW20MHz ()
+WifiPhy::GetHtMcs2 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate13MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 13000000,
- WIFI_CODE_RATE_1_2,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs2", 2, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetHtMcs3 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs3", 3, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate14_4MbpsBW20MHz ()
+WifiPhy::GetHtMcs4 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate14_4MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 14400000,
- WIFI_CODE_RATE_1_2,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs4", 4, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetHtMcs5 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs5", 5, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate19_5MbpsBW20MHz ()
+WifiPhy::GetHtMcs6 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate19_5MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 19500000,
- WIFI_CODE_RATE_3_4,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs6", 6, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate21_7MbpsBW20MHz ()
+WifiPhy::GetHtMcs7 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate21_7MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 21700000,
- WIFI_CODE_RATE_3_4,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs7", 7, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate26MbpsBW20MHz ()
+WifiPhy::GetHtMcs8 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate26MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 26000000,
- WIFI_CODE_RATE_1_2,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs8", 8, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetHtMcs9 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs9", 9, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate28_9MbpsBW20MHz ()
+WifiPhy::GetHtMcs10 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate28_9MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 28900000,
- WIFI_CODE_RATE_1_2,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs10", 10, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetHtMcs11 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs11", 11, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate39MbpsBW20MHz ()
+WifiPhy::GetHtMcs12 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate39MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 39000000,
- WIFI_CODE_RATE_3_4,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs12", 12, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate43_3MbpsBW20MHz ()
+WifiPhy::GetHtMcs13 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate43_3MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 43300000,
- WIFI_CODE_RATE_3_4,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs13", 13, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate52MbpsBW20MHz ()
+WifiPhy::GetHtMcs14 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate52MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 52000000,
- WIFI_CODE_RATE_2_3,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs14", 14, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate57_8MbpsBW20MHz ()
+WifiPhy::GetHtMcs15 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate57_8MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 57800000,
- WIFI_CODE_RATE_2_3,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs15", 15, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate58_5MbpsBW20MHz ()
+WifiPhy::GetHtMcs16 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate58_5MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 58500000,
- WIFI_CODE_RATE_3_4,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs16", 16, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate65MbpsBW20MHzShGi ()
+WifiPhy::GetHtMcs17 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate65MbpsBW20MHzShGi",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 65000000,
- WIFI_CODE_RATE_3_4,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs17", 17, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate65MbpsBW20MHz ()
+WifiPhy::GetHtMcs18 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate65MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- true,
- 20000000, 65000000,
- WIFI_CODE_RATE_5_6,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs18", 18, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate72_2MbpsBW20MHz ()
+WifiPhy::GetHtMcs19 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate72_2MbpsBW20MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 20000000, 72200000,
- WIFI_CODE_RATE_5_6,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs19", 19, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetHtMcs20 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs20", 20, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate13_5MbpsBW40MHz ()
+WifiPhy::GetHtMcs21 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 13500000,
- WIFI_CODE_RATE_1_2,
- 2);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs21", 21, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate15MbpsBW40MHz ()
+WifiPhy::GetHtMcs22 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate15MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 15000000,
- WIFI_CODE_RATE_1_2,
- 2);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs22", 22, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate27MbpsBW40MHz ()
+WifiPhy::GetHtMcs23 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 27000000,
- WIFI_CODE_RATE_1_2,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs23", 23, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetHtMcs24 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs24", 24, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate30MbpsBW40MHz ()
+WifiPhy::GetHtMcs25 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate30MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 30000000,
- WIFI_CODE_RATE_1_2,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs25", 25, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate40_5MbpsBW40MHz ()
+WifiPhy::GetHtMcs26 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate40_5MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 40500000,
- WIFI_CODE_RATE_3_4,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs26", 26, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate45MbpsBW40MHz ()
+WifiPhy::GetHtMcs27 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate45MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 45000000,
- WIFI_CODE_RATE_3_4,
- 4);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs27", 27, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate54MbpsBW40MHz ()
+WifiPhy::GetHtMcs28 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate54MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 54000000,
- WIFI_CODE_RATE_1_2,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs28", 28, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate60MbpsBW40MHz ()
+WifiPhy::GetHtMcs29 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate60MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 60000000,
- WIFI_CODE_RATE_1_2,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs29", 29, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetHtMcs30 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs30", 30, WIFI_MOD_CLASS_HT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate81MbpsBW40MHz ()
+WifiPhy::GetHtMcs31 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate81MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 81000000,
- WIFI_CODE_RATE_3_4,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("HtMcs31", 31, WIFI_MOD_CLASS_HT);
+ return mcs;
+}
+
+
+// Clause 22
+
+WifiMode
+WifiPhy::GetVhtMcs0 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs0", 0, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate90MbpsBW40MHz ()
+WifiPhy::GetVhtMcs1 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate90MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 90000000,
- WIFI_CODE_RATE_3_4,
- 16);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs1", 1, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate108MbpsBW40MHz ()
+WifiPhy::GetVhtMcs2 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate108MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 108000000,
- WIFI_CODE_RATE_2_3,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs2", 2, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate120MbpsBW40MHz ()
+WifiPhy::GetVhtMcs3 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate120MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 120000000,
- WIFI_CODE_RATE_2_3,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs3", 3, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate121_5MbpsBW40MHz ()
+WifiPhy::GetVhtMcs4 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate121_5MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 121500000,
- WIFI_CODE_RATE_3_4,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs4", 4, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate135MbpsBW40MHzShGi ()
+WifiPhy::GetVhtMcs5 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate135MbpsBW40MHzShGi",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 135000000,
- WIFI_CODE_RATE_3_4,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs5", 5, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate135MbpsBW40MHz ()
+WifiPhy::GetVhtMcs6 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate135MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 135000000,
- WIFI_CODE_RATE_5_6,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs6", 6, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
WifiMode
-WifiPhy::GetOfdmRate150MbpsBW40MHz ()
+WifiPhy::GetVhtMcs7 ()
{
- static WifiMode mode =
- WifiModeFactory::CreateWifiMode ("OfdmRate150MbpsBW40MHz",
- WIFI_MOD_CLASS_HT,
- false,
- 40000000, 150000000,
- WIFI_CODE_RATE_5_6,
- 64);
- return mode;
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs7", 7, WIFI_MOD_CLASS_VHT);
+ return mcs;
}
+WifiMode
+WifiPhy::GetVhtMcs8 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs8", 8, WIFI_MOD_CLASS_VHT);
+ return mcs;
+}
+
+WifiMode
+WifiPhy::GetVhtMcs9 ()
+{
+ static WifiMode mcs =
+ WifiModeFactory::CreateWifiMcs ("VhtMcs9", 9, WIFI_MOD_CLASS_VHT);
+ return mcs;
+}
std::ostream& operator<< (std::ostream& os, enum WifiPhy::State state)
{
@@ -1576,38 +1516,48 @@
ns3::WifiPhy::GetOfdmRate9MbpsBW5MHz ();
ns3::WifiPhy::GetOfdmRate12MbpsBW5MHz ();
ns3::WifiPhy::GetOfdmRate13_5MbpsBW5MHz ();
- ns3::WifiPhy::GetOfdmRate6_5MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate13MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate19_5MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate26MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate39MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate52MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate58_5MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate65MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate13_5MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate27MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate40_5MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate54MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate81MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate108MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate121_5MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate135MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate7_2MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate14_4MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate21_7MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate28_9MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate43_3MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate57_8MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate65MbpsBW20MHzShGi ();
- ns3::WifiPhy::GetOfdmRate72_2MbpsBW20MHz ();
- ns3::WifiPhy::GetOfdmRate15MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate30MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate45MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate60MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate90MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate120MbpsBW40MHz ();
- ns3::WifiPhy::GetOfdmRate135MbpsBW40MHzShGi ();
- ns3::WifiPhy::GetOfdmRate150MbpsBW40MHz ();
+ ns3::WifiPhy::GetHtMcs0 ();
+ ns3::WifiPhy::GetHtMcs1 ();
+ ns3::WifiPhy::GetHtMcs2 ();
+ ns3::WifiPhy::GetHtMcs3 ();
+ ns3::WifiPhy::GetHtMcs4 ();
+ ns3::WifiPhy::GetHtMcs5 ();
+ ns3::WifiPhy::GetHtMcs6 ();
+ ns3::WifiPhy::GetHtMcs7 ();
+ ns3::WifiPhy::GetHtMcs8 ();
+ ns3::WifiPhy::GetHtMcs9 ();
+ ns3::WifiPhy::GetHtMcs10 ();
+ ns3::WifiPhy::GetHtMcs11 ();
+ ns3::WifiPhy::GetHtMcs12 ();
+ ns3::WifiPhy::GetHtMcs13 ();
+ ns3::WifiPhy::GetHtMcs14 ();
+ ns3::WifiPhy::GetHtMcs15 ();
+ ns3::WifiPhy::GetHtMcs16 ();
+ ns3::WifiPhy::GetHtMcs17 ();
+ ns3::WifiPhy::GetHtMcs18 ();
+ ns3::WifiPhy::GetHtMcs19 ();
+ ns3::WifiPhy::GetHtMcs20 ();
+ ns3::WifiPhy::GetHtMcs21 ();
+ ns3::WifiPhy::GetHtMcs22 ();
+ ns3::WifiPhy::GetHtMcs23 ();
+ ns3::WifiPhy::GetHtMcs24 ();
+ ns3::WifiPhy::GetHtMcs25 ();
+ ns3::WifiPhy::GetHtMcs26 ();
+ ns3::WifiPhy::GetHtMcs27 ();
+ ns3::WifiPhy::GetHtMcs28 ();
+ ns3::WifiPhy::GetHtMcs29 ();
+ ns3::WifiPhy::GetHtMcs30 ();
+ ns3::WifiPhy::GetHtMcs31 ();
+ ns3::WifiPhy::GetVhtMcs0 ();
+ ns3::WifiPhy::GetVhtMcs1 ();
+ ns3::WifiPhy::GetVhtMcs2 ();
+ ns3::WifiPhy::GetVhtMcs3 ();
+ ns3::WifiPhy::GetVhtMcs4 ();
+ ns3::WifiPhy::GetVhtMcs5 ();
+ ns3::WifiPhy::GetVhtMcs6 ();
+ ns3::WifiPhy::GetVhtMcs7 ();
+ ns3::WifiPhy::GetVhtMcs8 ();
+ ns3::WifiPhy::GetVhtMcs9 ();
}
} g_constructor;
--- a/src/wifi/model/wifi-phy.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-phy.h Thu Sep 03 22:16:49 2015 +0200
@@ -15,7 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#ifndef WIFI_PHY_H
@@ -309,7 +310,7 @@
Time CalculateTxDuration (uint32_t size, WifiTxVector txVector, enum WifiPreamble preamble, double frequency, uint8_t packetType, uint8_t incFlag);
/**
- * \param txVector the TXVECTOR used for the transmission of this packet
+ * \param txVector the transmission parameters used for this packet
* \param preamble the type of preamble to use for this packet.
*
* \return the total amount of time this PHY will stay busy for the transmission of the PLCP preamble and PLCP header.
@@ -329,7 +330,13 @@
* \return the WifiMode used for the transmission of the HT-SIG and the HT training fields
* in Mixed Format and greenfield format PLCP header
*/
- static WifiMode GetHTPlcpHeaderMode (WifiMode payloadMode);
+ static WifiMode GetHtPlcpHeaderMode (WifiMode payloadMode);
+ /**
+ * \param payloadMode the WifiMode use for the transmission of the payload
+ *
+ * \return the WifiMode used for the transmission of the VHT-STF, VHT-LTF and VHT-SIG-B fields
+ */
+ static WifiMode GetVhtPlcpHeaderMode (WifiMode payloadMode);
/**
* \param preamble the type of preamble
*
@@ -337,26 +344,45 @@
*/
static Time GetPlcpHtSigHeaderDuration (WifiPreamble preamble);
/**
+ * \param preamble the type of preamble
+ *
+ * \return the duration of the VHT-SIG-A1 in PLCP header
+ */
+ static Time GetPlcpVhtSigA1Duration (WifiPreamble preamble);
+ /**
+ * \param preamble the type of preamble
+ *
+ * \return the duration of the VHT-SIG-A2 in PLCP header
+ */
+ static Time GetPlcpVhtSigA2Duration (WifiPreamble preamble);
+ /**
+ * \param preamble the type of preamble
+ *
+ * \return the duration of the VHT-SIG-B in PLCP header
+ */
+ static Time GetPlcpVhtSigBDuration (WifiPreamble preamble);
+ /**
* \param payloadMode the WifiMode use for the transmission of the payload
* \param preamble the type of preamble
+ * \param txVector the transmission parameters used for this packet
*
* \return the WifiMode used for the transmission of the PLCP header
*/
- static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
+ static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble, WifiTxVector txVector);
/**
- * \param payloadMode the WifiMode use for the transmission of the payload
+ * \param txVector the transmission parameters used for this packet
* \param preamble the type of preamble
*
* \return the duration of the PLCP header
*/
- static Time GetPlcpHeaderDuration (WifiMode payloadMode, WifiPreamble preamble);
+ static Time GetPlcpHeaderDuration (WifiTxVector txVector, WifiPreamble preamble);
/**
- * \param payloadMode the WifiMode use for the transmission of the payload
+ * \param txVector the transmission parameters used for this packet
* \param preamble the type of preamble
*
* \return the duration of the PLCP preamble
*/
- static Time GetPlcpPreambleDuration (WifiMode payloadMode, WifiPreamble preamble);
+ static Time GetPlcpPreambleDuration (WifiTxVector txVector, WifiPreamble preamble);
/**
* \param size the number of bytes in the packet to send
* \param txVector the TXVECTOR used for the transmission of this packet
@@ -483,26 +509,7 @@
*
* \return the MCS index whose index is specified.
*/
- virtual uint8_t GetMcs (uint8_t mcs) const = 0;
-
- /**
- * For a given WifiMode finds the corresponding MCS value and returns it
- * as defined in the IEEE 802.11n standard
- *
- * \param mode the WifiMode
- *
- * \return the MCS number that corresponds to the given WifiMode
- */
- virtual uint32_t WifiModeToMcs (WifiMode mode) = 0;
- /**
- * For a given MCS finds the corresponding WifiMode and returns it
- * as defined in the IEEE 802.11n standard.
- *
- * \param mcs the MCS number
- *
- * \return the WifiMode that corresponds to the given MCS number
- */
- virtual WifiMode McsToWifiMode (uint8_t mcs) = 0;
+ virtual WifiMode GetMcs (uint8_t mcs) const = 0;
/**
* \brief Set channel number.
@@ -756,200 +763,260 @@
* \return a WifiMode for OFDM at 13.5Mbps with 5MHz channel spacing
*/
static WifiMode GetOfdmRate13_5MbpsBW5MHz ();
+
/**
- * Return a WifiMode for OFDM at 6.5Mbps with 20MHz channel spacing.
+ * Return MCS 0 from HT MCS values.
*
- * \return a WifiMode for OFDM at 6.5Mbps with 20MHz channel spacing
+ * \return MCS 0 from HT MCS values
*/
- static WifiMode GetOfdmRate6_5MbpsBW20MHz ();
+ static WifiMode GetHtMcs0 ();
/**
- * Return a WifiMode for OFDM at 13Mbps with 20MHz channel spacing.
+ * Return MCS 1 from HT MCS values.
*
- * \return a WifiMode for OFDM at 13Mbps with 20MHz channel spacing
+ * \return MCS 1 from HT MCS values
*/
- static WifiMode GetOfdmRate13MbpsBW20MHz ();
+ static WifiMode GetHtMcs1 ();
/**
- * Return a WifiMode for OFDM at 19.5Mbps with 20MHz channel spacing.
+ * Return MCS 2 from HT MCS values.
*
- * \return a WifiMode for OFDM at 19.5Mbps with 20MHz channel spacing
+ * \return MCS 2 from HT MCS values
*/
- static WifiMode GetOfdmRate19_5MbpsBW20MHz ();
+ static WifiMode GetHtMcs2 ();
/**
- * Return a WifiMode for OFDM at 26Mbps with 20MHz channel spacing.
+ * Return MCS 3 from HT MCS values.
*
- * \return a WifiMode for OFDM at 26Mbps with 20MHz channel spacing
+ * \return MCS 3 from HT MCS values
+ */
+ static WifiMode GetHtMcs3 ();
+ /**
+ * Return MCS 4 from HT MCS values.
+ *
+ * \return MCS 4 from HT MCS values
*/
- static WifiMode GetOfdmRate26MbpsBW20MHz ();
+ static WifiMode GetHtMcs4 ();
/**
- * Return a WifiMode for OFDM at 39Mbps with 20MHz channel spacing.
+ * Return MCS 5 from HT MCS values.
*
- * \return a WifiMode for OFDM at 39Mbps with 20MHz channel spacing
+ * \return MCS 5 from HT MCS values
*/
- static WifiMode GetOfdmRate39MbpsBW20MHz ();
+ static WifiMode GetHtMcs5 ();
/**
- * Return a WifiMode for OFDM at 52Mbps with 20MHz channel spacing.
+ * Return MCS 6 from HT MCS values.
*
- * \return a WifiMode for OFDM at 52Mbps with 20MHz channel spacing
+ * \return MCS 6 from HT MCS values
*/
- static WifiMode GetOfdmRate52MbpsBW20MHz ();
+ static WifiMode GetHtMcs6 ();
/**
- * Return a WifiMode for OFDM at 58.5Mbps with 20MHz channel spacing.
+ * Return MCS 7 from HT MCS values.
*
- * \return a WifiMode for OFDM at 58.5Mbps with 20MHz channel spacing
+ * \return MCS 7 from HT MCS values
*/
- static WifiMode GetOfdmRate58_5MbpsBW20MHz ();
+ static WifiMode GetHtMcs7 ();
/**
- * Return a WifiMode for OFDM at 65Mbps with 20MHz channel spacing.
+ * Return MCS 8 from HT MCS values.
*
- * \return a WifiMode for OFDM at 65Mbps with 20MHz channel spacing
+ * \return MCS 8 from HT MCS values
+ */
+ static WifiMode GetHtMcs8 ();
+ /**
+ * Return MCS 9 from HT MCS values.
+ *
+ * \return MCS 9 from HT MCS values
*/
- static WifiMode GetOfdmRate65MbpsBW20MHz ();
+ static WifiMode GetHtMcs9 ();
/**
- * Return a WifiMode for OFDM at 13.5Mbps with 40MHz channel spacing.
+ * Return MCS 10 from HT MCS values.
*
- * \return a WifiMode for OFDM at 13.5Mbps with 40MHz channel spacing
+ * \return MCS 10 from HT MCS values
*/
- static WifiMode GetOfdmRate13_5MbpsBW40MHz ();
+ static WifiMode GetHtMcs10 ();
/**
- * Return a WifiMode for OFDM at 27Mbps with 40MHz channel spacing.
+ * Return MCS 11 from HT MCS values.
*
- * \return a WifiMode for OFDM at 27Mbps with 40MHz channel spacing
+ * \return MCS 11 from HT MCS values
*/
- static WifiMode GetOfdmRate27MbpsBW40MHz ();
+ static WifiMode GetHtMcs11 ();
/**
- * Return a WifiMode for OFDM at 40.5Mbps with 40MHz channel spacing.
+ * Return MCS 12 from HT MCS values.
*
- * \return a WifiMode for OFDM at 40.5Mbps with 40MHz channel spacing
+ * \return MCS 12 from HT MCS values
*/
- static WifiMode GetOfdmRate40_5MbpsBW40MHz ();
+ static WifiMode GetHtMcs12 ();
/**
- * Return a WifiMode for OFDM at 54Mbps with 40MHz channel spacing.
+ * Return MCS 13 from HT MCS values.
*
- * \return a WifiMode for OFDM at 54Mbps with 40MHz channel spacing
+ * \return MCS 13 from HT MCS values
+ */
+ static WifiMode GetHtMcs13 ();
+ /**
+ * Return MCS 14 from HT MCS values.
+ *
+ * \return MCS 14 from HT MCS values
*/
- static WifiMode GetOfdmRate54MbpsBW40MHz ();
+ static WifiMode GetHtMcs14 ();
/**
- * Return a WifiMode for OFDM at 81Mbps with 40MHz channel spacing.
+ * Return MCS 15 from HT MCS values.
*
- * \return a WifiMode for OFDM at 81Mbps with 40MHz channel spacing
+ * \return MCS 15 from HT MCS values
*/
- static WifiMode GetOfdmRate81MbpsBW40MHz ();
+ static WifiMode GetHtMcs15 ();
/**
- * Return a WifiMode for OFDM at 108Mbps with 40MHz channel spacing.
+ * Return MCS 16 from HT MCS values.
*
- * \return a WifiMode for OFDM at 108Mbps with 40MHz channel spacing
+ * \return MCS 16 from HT MCS values
*/
- static WifiMode GetOfdmRate108MbpsBW40MHz ();
+ static WifiMode GetHtMcs16 ();
/**
- * Return a WifiMode for OFDM at 121.5Mbps with 40MHz channel spacing.
+ * Return MCS 17 from HT MCS values.
*
- * \return a WifiMode for OFDM at 121.5Mbps with 40MHz channel spacing
+ * \return MCS 17 from HT MCS values
*/
- static WifiMode GetOfdmRate121_5MbpsBW40MHz ();
+ static WifiMode GetHtMcs17 ();
/**
- * Return a WifiMode for OFDM at 135Mbps with 40MHz channel spacing.
+ * Return MCS 18 from HT MCS values.
*
- * \return a WifiMode for OFDM at 135Mbps with 40MHz channel spacing
+ * \return MCS 18 from HT MCS values
*/
- static WifiMode GetOfdmRate135MbpsBW40MHz ();
+ static WifiMode GetHtMcs18 ();
+ /**
+ * Return MCS 19 from HT MCS values.
+ *
+ * \return MCS 19 from HT MCS values
+ */
+ static WifiMode GetHtMcs19 ();
/**
- * Return a WifiMode for OFDM at 7.2Mbps with 20MHz channel spacing.
+ * Return MCS 20 from HT MCS values.
*
- * \return a WifiMode for OFDM at 7.2Mbps with 20MHz channel spacing
+ * \return MCS 20 from HT MCS values
*/
- static WifiMode GetOfdmRate7_2MbpsBW20MHz ();
+ static WifiMode GetHtMcs20 ();
/**
- * Return a WifiMode for OFDM at 14.4Mbps with 20MHz channel spacing.
+ * Return MCS 21 from HT MCS values.
*
- * \return a WifiMode for OFDM at 14.4Mbps with 20MHz channel spacing
+ * \return MCS 21 from HT MCS values
*/
- static WifiMode GetOfdmRate14_4MbpsBW20MHz ();
+ static WifiMode GetHtMcs21 ();
/**
- * Return a WifiMode for OFDM at 21.7Mbps with 20MHz channel spacing.
+ * Return MCS 22 from HT MCS values.
*
- * \return a WifiMode for OFDM at 21.7Mbps with 20MHz channel spacing
+ * \return MCS 22 from HT MCS values
*/
- static WifiMode GetOfdmRate21_7MbpsBW20MHz ();
+ static WifiMode GetHtMcs22 ();
/**
- * Return a WifiMode for OFDM at 28.9Mbps with 20MHz channel spacing.
+ * Return MCS 23 from HT MCS values.
*
- * \return a WifiMode for OFDM at 28.9Mbps with 20MHz channel spacing
+ * \return MCS 23 from HT MCS values
*/
- static WifiMode GetOfdmRate28_9MbpsBW20MHz ();
+ static WifiMode GetHtMcs23 ();
+ /**
+ * Return MCS 24 from HT MCS values.
+ *
+ * \return MCS 24 from HT MCS values
+ */
+ static WifiMode GetHtMcs24 ();
/**
- * Return a WifiMode for OFDM at 43.3Mbps with 20MHz channel spacing.
+ * Return MCS 25 from HT MCS values.
*
- * \return a WifiMode for OFDM at 43.3Mbps with 20MHz channel spacing
+ * \return MCS 25 from HT MCS values
*/
- static WifiMode GetOfdmRate43_3MbpsBW20MHz ();
+ static WifiMode GetHtMcs25 ();
/**
- * Return a WifiMode for OFDM at 57.8Mbps with 20MHz channel spacing.
+ * Return MCS 26 from HT MCS values.
*
- * \return a WifiMode for OFDM at 57.8Mbps with 20MHz channel spacing
+ * \return MCS 26 from HT MCS values
*/
- static WifiMode GetOfdmRate57_8MbpsBW20MHz ();
+ static WifiMode GetHtMcs26 ();
+ /**
+ * Return MCS 27 from HT MCS values.
+ *
+ * \return MCS 27 from HT MCS values
+ */
+ static WifiMode GetHtMcs27 ();
/**
- * Return a WifiMode for OFDM at 65Mbps with 20MHz channel spacing.
- * The rate supports short guard interval.
+ * Return MCS 28 from HT MCS values.
*
- * \return a WifiMode for OFDM at 65Mbps with 20MHz channel spacing
+ * \return MCS 28 from HT MCS values
*/
- static WifiMode GetOfdmRate65MbpsBW20MHzShGi ();
+ static WifiMode GetHtMcs28 ();
/**
- * Return a WifiMode for OFDM at 72.2Mbps with 20MHz channel spacing.
+ * Return MCS 29 from HT MCS values.
*
- * \return a WifiMode for OFDM at 72.2Mbps with 20MHz channel spacing
+ * \return MCS 29 from HT MCS values
*/
- static WifiMode GetOfdmRate72_2MbpsBW20MHz ();
+ static WifiMode GetHtMcs29 ();
+ /**
+ * Return MCS 30 from HT MCS values.
+ *
+ * \return MCS 30 from HT MCS values
+ */
+ static WifiMode GetHtMcs30 ();
/**
- * Return a WifiMode for OFDM at 15Mbps with 40MHz channel spacing.
+ * Return MCS 31 from HT MCS values.
*
- * \return a WifiMode for OFDM at 15Mbps with 40MHz channel spacing
+ * \return MCS 31 from HT MCS values
*/
- static WifiMode GetOfdmRate15MbpsBW40MHz ();
+ static WifiMode GetHtMcs31 ();
+
/**
- * Return a WifiMode for OFDM at 30Mbps with 40MHz channel spacing.
+ * Return MCS 0 from VHT MCS values.
*
- * \return a WifiMode for OFDM at 30Mbps with 40MHz channel spacing
+ * \return MCS 0 from VHT MCS values
*/
- static WifiMode GetOfdmRate30MbpsBW40MHz ();
+ static WifiMode GetVhtMcs0 ();
/**
- * Return a WifiMode for OFDM at 45Mbps with 40MHz channel spacing.
+ * Return MCS 1 from VHT MCS values.
*
- * \return a WifiMode for OFDM at 45Mbps with 40MHz channel spacing
+ * \return MCS 1 from VHT MCS values
*/
- static WifiMode GetOfdmRate45MbpsBW40MHz ();
+ static WifiMode GetVhtMcs1 ();
/**
- * Return a WifiMode for OFDM at 60Mbps with 40MHz channel spacing.
+ * Return MCS 2 from VHT MCS values.
*
- * \return a WifiMode for OFDM at 60Mbps with 40MHz channel spacing
+ * \return MCS 2 from VHT MCS values
*/
- static WifiMode GetOfdmRate60MbpsBW40MHz ();
+ static WifiMode GetVhtMcs2 ();
+ /**
+ * Return MCS 3 from VHT MCS values.
+ *
+ * \return MCS 3 from VHT MCS values
+ */
+ static WifiMode GetVhtMcs3 ();
/**
- * Return a WifiMode for OFDM at 90Mbps with 40MHz channel spacing.
+ * Return MCS 4 from VHT MCS values.
*
- * \return a WifiMode for OFDM at 90Mbps with 40MHz channel spacing
+ * \return MCS 4 from VHT MCS values
*/
- static WifiMode GetOfdmRate90MbpsBW40MHz ();
+ static WifiMode GetVhtMcs4 ();
/**
- * Return a WifiMode for OFDM at 120Mbps with 40MHz channel spacing.
+ * Return MCS 5 from VHT MCS values.
*
- * \return a WifiMode for OFDM at 120Mbps with 40MHz channel spacing
+ * \return MCS 5 from VHT MCS values
*/
- static WifiMode GetOfdmRate120MbpsBW40MHz ();
+ static WifiMode GetVhtMcs5 ();
+ /**
+ * Return MCS 6 from VHT MCS values.
+ *
+ * \return MCS 6 from VHT MCS values
+ */
+ static WifiMode GetVhtMcs6 ();
/**
- * Return a WifiMode for OFDM at 135Mbps with 40MHz channel spacing.
- * The rate supports short guard interval.
+ * Return MCS 7 from VHT MCS values.
*
- * \return a WifiMode for OFDM at 135Mbps with 40MHz channel spacing
+ * \return MCS 7 from VHT MCS values
*/
- static WifiMode GetOfdmRate135MbpsBW40MHzShGi ();
+ static WifiMode GetVhtMcs7 ();
/**
- * Return a WifiMode for OFDM at 150Mbps with 40MHz channel spacing.
+ * Return MCS 8 from VHT MCS values.
*
- * \return a WifiMode for OFDM at 150Mbps with 40MHz channel spacing
+ * \return MCS 8 from VHT MCS values
*/
- static WifiMode GetOfdmRate150MbpsBW40MHz ();
+ static WifiMode GetVhtMcs8 ();
+ /**
+ * Return MCS 9 from VHT MCS values.
+ *
+ * \return MCS 9 from VHT MCS values
+ */
+ static WifiMode GetVhtMcs9 ();
/**
* Public method used to fire a PhyTxBegin trace.
@@ -1042,11 +1109,10 @@
* \todo WifiTxVector should be passed by const reference because
* of its size.
*/
- typedef void (* MonitorSnifferRxCallback)
- (Ptr<const Packet> packet, uint16_t channelFreqMhz,
- uint16_t channelNumber, uint32_t rate, WifiPreamble preamble,
- WifiTxVector txVector, struct mpduInfo aMpdu,
- struct signalNoiseDbm signalNoise);
+ typedef void (* MonitorSnifferRxCallback)(Ptr<const Packet> packet, uint16_t channelFreqMhz,
+ uint16_t channelNumber, uint32_t rate, WifiPreamble preamble,
+ WifiTxVector txVector, struct mpduInfo aMpdu,
+ struct signalNoiseDbm signalNoise);
/**
* Public method used to fire a MonitorSniffer trace for a wifi packet being transmitted.
@@ -1083,10 +1149,9 @@
* \todo WifiTxVector should be passed by const reference because
* of its size.
*/
- typedef void (* MonitorSnifferTxCallback)
- (const Ptr<const Packet> packet, uint16_t channelFreqMhz,
- uint16_t channelNumber, uint32_t rate, WifiPreamble preamble,
- WifiTxVector txVector, struct mpduInfo aMpdu);
+ typedef void (* MonitorSnifferTxCallback)(const Ptr<const Packet> packet, uint16_t channelFreqMhz,
+ uint16_t channelNumber, uint32_t rate, WifiPreamble preamble,
+ WifiTxVector txVector, struct mpduInfo aMpdu);
/**
* Assign a fixed random variable stream number to the random variables
@@ -1143,7 +1208,7 @@
*/
virtual void SetStbc (bool stbc) = 0;
/**
- * \return true if STBC is supported, false otherwise
+ * \return true if STBC is supported, false otherwise
*/
virtual bool GetStbc (void) const = 0;
/**
@@ -1155,13 +1220,13 @@
*/
virtual bool GetGreenfield (void) const = 0;
/**
- * \return true if channel bonding 40 MHz is supported, false otherwise
+ * \return the channel width
*/
- virtual bool GetChannelBonding (void) const = 0;
+ virtual uint32_t GetChannelWidth (void) const = 0;
/**
- * \param channelbonding Enable or disable channel bonding
+ * \param channelwidth channel width
*/
- virtual void SetChannelBonding (bool channelbonding) = 0;
+ virtual void SetChannelWidth (uint32_t channelwidth) = 0;
private:
--- a/src/wifi/model/wifi-preamble.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-preamble.h Thu Sep 03 22:16:49 2015 +0200
@@ -33,6 +33,7 @@
WIFI_PREAMBLE_SHORT,
WIFI_PREAMBLE_HT_MF,
WIFI_PREAMBLE_HT_GF,
+ WIFI_PREAMBLE_VHT,
WIFI_PREAMBLE_NONE
};
--- a/src/wifi/model/wifi-remote-station-manager.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-remote-station-manager.cc Thu Sep 03 22:16:49 2015 +0200
@@ -378,14 +378,10 @@
//acknowledgements.
m_wifiPhy = phy;
m_defaultTxMode = phy->GetMode (0);
- if (HasHtSupported ())
+ if (HasHtSupported () || HasVhtSupported ())
{
m_defaultTxMcs = phy->GetMcs (0);
}
- else
- {
- m_defaultTxMcs = 0;
- }
Reset ();
}
@@ -434,6 +430,18 @@
return m_htSupported;
}
+void
+WifiRemoteStationManager::SetVhtSupported (bool enable)
+{
+ m_vhtSupported = enable;
+}
+
+bool
+WifiRemoteStationManager::HasVhtSupported (void) const
+{
+ return m_vhtSupported;
+}
+
uint32_t
WifiRemoteStationManager::GetMaxSsrc (void) const
{
@@ -500,12 +508,12 @@
}
void
-WifiRemoteStationManager::AddSupportedMcs (Mac48Address address, uint8_t mcs)
+WifiRemoteStationManager::AddSupportedMcs (Mac48Address address, WifiMode mcs)
{
- NS_LOG_FUNCTION (this << address << (uint16_t) mcs);
+ NS_LOG_FUNCTION (this << address << mcs);
NS_ASSERT (!address.IsGroup ());
WifiRemoteStationState *state = LookupState (address);
- for (WifiMcsListIterator i = state->m_operationalMcsSet.begin (); i != state->m_operationalMcsSet.end (); i++)
+ for (WifiModeListIterator i = state->m_operationalMcsSet.begin (); i != state->m_operationalMcsSet.end (); i++)
{
if ((*i) == mcs)
{
@@ -613,6 +621,7 @@
WifiTxVector v;
v.SetMode (GetNonUnicastMode ());
v.SetTxPowerLevel (m_defaultTxPowerLevel);
+ v.SetChannelWidth (20);
v.SetShortGuardInterval (false);
v.SetNss (1);
v.SetNess (0);
@@ -658,6 +667,7 @@
return WifiTxVector (GetDefaultMode (),
GetDefaultTxPowerLevel (),
0,
+ m_wifiPhy->GetChannelWidth (),
m_wifiPhy->GetGuardInterval (),
GetNumberOfTransmitAntennas (),
GetNumberOfTransmitAntennas (),
@@ -797,12 +807,10 @@
}
if (HasHtSupported ())
{
- uint8_t mcs = m_wifiPhy->WifiModeToMcs (mode);
//search for the BSS Basic MCS set, if the used mode is in the basic set then there is no need for Cts To Self
- for (WifiMcsListIterator i = m_bssBasicMcsSet.begin ();
- i != m_bssBasicMcsSet.end (); i++)
+ for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++)
{
- if (mcs == *i)
+ if (mode == *i)
{
NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning false");
return false;
@@ -981,14 +989,15 @@
NS_LOG_FUNCTION (this << address << reqMode);
WifiMode mode = GetDefaultMode ();
bool found = false;
-
//First, search the BSS Basic Rate set
for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++)
{
- if ((!found || i->GetPhyRate () > mode.GetPhyRate ())
- && (i->GetPhyRate () <= reqMode.GetPhyRate ())
+ if ((!found || i->GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1))
+ && (i->GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1))
&& ((i->GetModulationClass () == reqMode.GetModulationClass ())
- || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT)))
+ || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
+ || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)))
+
{
mode = *i;
//We've found a potentially-suitable transmit rate, but we
@@ -997,21 +1006,18 @@
found = true;
}
}
- if (HasHtSupported ())
+ if (HasHtSupported () || HasVhtSupported ())
{
if (!found)
{
- uint8_t mcs = GetDefaultMcs ();
- mode = m_wifiPhy->McsToWifiMode (mcs);
-
- for (WifiMcsListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++)
+ mode = GetDefaultMcs ();
+ for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++)
{
- WifiMode thismode = m_wifiPhy->McsToWifiMode (*i);
- if ((!found || thismode.GetPhyRate () > mode.GetPhyRate ())
- && thismode.GetPhyRate () <= reqMode.GetPhyRate ()
- && thismode.GetModulationClass () == reqMode.GetModulationClass ())
+ if ((!found || i->GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1))
+ && i->GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1))
+ //&& thismode.GetModulationClass () == reqMode.GetModulationClass ()) //TODO: check standard
{
- mode = thismode;
+ mode = *i;
//We've found a potentially-suitable transmit rate, but we
//need to continue and consider all the basic rates before
//we can be sure we've got the right one.
@@ -1059,10 +1065,12 @@
* ...then it's our best choice so far.
*/
if (thismode.IsMandatory ()
- && (!found || thismode.GetPhyRate () > mode.GetPhyRate ())
- && (thismode.GetPhyRate () <= reqMode.GetPhyRate ())
+ && (!found || thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1))
+ && (thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1))
&& ((thismode.GetModulationClass () == reqMode.GetModulationClass ())
+ || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|| (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT)))
+
{
mode = thismode;
//As above; we've found a potentially-suitable transmit
@@ -1071,15 +1079,14 @@
found = true;
}
}
- if (HasHtSupported ())
+ if (HasHtSupported () || HasVhtSupported ())
{
for (uint32_t idx = 0; idx < m_wifiPhy->GetNMcs (); idx++)
{
- uint8_t thismcs = m_wifiPhy->GetMcs (idx);
- WifiMode thismode = m_wifiPhy->McsToWifiMode (thismcs);
+ WifiMode thismode = m_wifiPhy->GetMcs (idx);
if (thismode.IsMandatory ()
- && (!found || thismode.GetPhyRate () > mode.GetPhyRate ())
- && thismode.GetPhyRate () <= reqMode.GetPhyRate ()
+ && (!found || thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1))
+ && thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), 1)
&& thismode.GetModulationClass () == reqMode.GetModulationClass ())
{
mode = thismode;
@@ -1118,6 +1125,7 @@
WifiTxVector v;
v.SetMode (GetControlAnswerMode (address, rtsMode));
v.SetTxPowerLevel (DoGetCtsTxPowerLevel (address, v.GetMode ()));
+ v.SetChannelWidth (DoGetCtsTxChannelWidth (address, v.GetMode ()));
v.SetShortGuardInterval (DoGetCtsTxGuardInterval (address, v.GetMode ()));
v.SetNss (DoGetCtsTxNss (address, v.GetMode ()));
v.SetNess (DoGetCtsTxNess (address, v.GetMode ()));
@@ -1132,6 +1140,7 @@
WifiTxVector v;
v.SetMode (GetControlAnswerMode (address, dataMode));
v.SetTxPowerLevel (DoGetAckTxPowerLevel (address, v.GetMode ()));
+ v.SetChannelWidth (DoGetAckTxChannelWidth (address, v.GetMode ()));
v.SetShortGuardInterval (DoGetAckTxGuardInterval (address, v.GetMode ()));
v.SetNss (DoGetAckTxNss (address, v.GetMode ()));
v.SetNess (DoGetAckTxNess (address, v.GetMode ()));
@@ -1146,6 +1155,7 @@
WifiTxVector v;
v.SetMode (GetControlAnswerMode (address, blockAckReqMode));
v.SetTxPowerLevel (DoGetBlockAckTxPowerLevel (address, v.GetMode ()));
+ v.SetChannelWidth (DoGetBlockAckTxChannelWidth (address, v.GetMode ()));
v.SetShortGuardInterval (DoGetBlockAckTxGuardInterval (address, v.GetMode ()));
v.SetNss (DoGetBlockAckTxNss (address, v.GetMode ()));
v.SetNess (DoGetBlockAckTxNess (address, v.GetMode ()));
@@ -1159,6 +1169,12 @@
return m_defaultTxPowerLevel;
}
+uint32_t
+WifiRemoteStationManager::DoGetCtsTxChannelWidth (Mac48Address address, WifiMode ctsMode)
+{
+ return m_wifiPhy->GetChannelWidth ();
+}
+
bool
WifiRemoteStationManager::DoGetCtsTxGuardInterval (Mac48Address address, WifiMode ctsMode)
{
@@ -1189,6 +1205,12 @@
return m_defaultTxPowerLevel;
}
+uint32_t
+WifiRemoteStationManager::DoGetAckTxChannelWidth (Mac48Address address, WifiMode ctsMode)
+{
+ return m_wifiPhy->GetChannelWidth ();
+}
+
bool
WifiRemoteStationManager::DoGetAckTxGuardInterval (Mac48Address address, WifiMode ackMode)
{
@@ -1219,6 +1241,12 @@
return m_defaultTxPowerLevel;
}
+uint32_t
+WifiRemoteStationManager::DoGetBlockAckTxChannelWidth (Mac48Address address, WifiMode ctsMode)
+{
+ return m_wifiPhy->GetChannelWidth ();
+}
+
bool
WifiRemoteStationManager::DoGetBlockAckTxGuardInterval (Mac48Address address, WifiMode blockAckMode)
{
@@ -1273,6 +1301,7 @@
state->m_address = address;
state->m_operationalRateSet.push_back (GetDefaultMode ());
state->m_operationalMcsSet.push_back (GetDefaultMcs ());
+ state->m_channelWidth = m_wifiPhy->GetChannelWidth ();
state->m_shortGuardInterval = m_wifiPhy->GetGuardInterval ();
state->m_greenfield = m_wifiPhy->GetGreenfield ();
state->m_rx = 1;
@@ -1321,24 +1350,53 @@
station->m_slrc = 0;
const_cast<WifiRemoteStationManager *> (this)->m_stations.push_back (station);
return station;
-
}
void
-WifiRemoteStationManager::AddStationHtCapabilities (Mac48Address from, HtCapabilities htcapabilities)
+WifiRemoteStationManager::AddStationHtCapabilities (Mac48Address from, HtCapabilities htCapabilities)
{
//Used by all stations to record HT capabilities of remote stations
- NS_LOG_FUNCTION (this << from << htcapabilities);
+ NS_LOG_FUNCTION (this << from << htCapabilities);
WifiRemoteStationState *state;
state = LookupState (from);
- state->m_shortGuardInterval = htcapabilities.GetShortGuardInterval20 ();
- state->m_greenfield = htcapabilities.GetGreenfield ();
+ state->m_shortGuardInterval = htCapabilities.GetShortGuardInterval20 ();
+ if (htCapabilities.GetSupportedChannelWidth () == 1)
+ {
+ state->m_channelWidth = 40;
+ }
+ else
+ {
+ state->m_channelWidth = 20;
+ }
+ state->m_greenfield = htCapabilities.GetGreenfield ();
+}
+
+void
+WifiRemoteStationManager::AddStationVhtCapabilities (Mac48Address from, VhtCapabilities vhtCapabilities)
+{
+ //Used by all stations to record VHT capabilities of remote stations
+ NS_LOG_FUNCTION (this << from << vhtCapabilities);
+ WifiRemoteStationState *state;
+ state = LookupState (from);
+ if (vhtCapabilities.GetSupportedChannelWidthSet () == 1)
+ {
+ state->m_channelWidth = 160;
+ }
+ else
+ {
+ state->m_channelWidth = 80;
+ }
+ //This is a workaround to enable users to force a 20 or 40 MHz channel for a VHT-compliant device,
+ //since IEEE 802.11ac standard says that 20, 40 and 80 MHz channels are mandatory.
+ if (m_wifiPhy->GetChannelWidth () < state->m_channelWidth)
+ {
+ state->m_channelWidth = m_wifiPhy->GetChannelWidth ();
+ }
}
bool
WifiRemoteStationManager::GetGreenfieldSupported (Mac48Address address) const
{
- //Used by mac low to choose format used GF, MF or Non HT
return LookupState (address)->m_greenfield;
}
@@ -1348,7 +1406,7 @@
return m_defaultTxMode;
}
-uint8_t
+WifiMode
WifiRemoteStationManager::GetDefaultMcs (void) const
{
return m_defaultTxMcs;
@@ -1374,9 +1432,9 @@
WifiRemoteStationManager::AddBasicMode (WifiMode mode)
{
NS_LOG_FUNCTION (this << mode);
- if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
+ if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
{
- NS_FATAL_ERROR ("It is not allowed to add a HT rate in the BSSBasicRateSet!");
+ NS_FATAL_ERROR ("It is not allowed to add a (V)HT rate in the BSSBasicRateSet!");
}
for (uint32_t i = 0; i < GetNBasicModes (); i++)
{
@@ -1402,9 +1460,9 @@
}
void
-WifiRemoteStationManager::AddBasicMcs (uint8_t mcs)
+WifiRemoteStationManager::AddBasicMcs (WifiMode mcs)
{
- NS_LOG_FUNCTION (this << (uint32_t)mcs);
+ NS_LOG_FUNCTION (this << (uint32_t)mcs.GetMcsValue ());
for (uint32_t i = 0; i < GetNBasicMcs (); i++)
{
if (GetBasicMcs (i) == mcs)
@@ -1421,7 +1479,7 @@
return m_bssBasicMcsSet.size ();
}
-uint8_t
+WifiMode
WifiRemoteStationManager::GetBasicMcs (uint32_t i) const
{
NS_ASSERT (i < m_bssBasicMcsSet.size ());
@@ -1476,13 +1534,19 @@
return station->m_state->m_operationalRateSet[i];
}
-uint8_t
+WifiMode
WifiRemoteStationManager::GetMcsSupported (const WifiRemoteStation *station, uint32_t i) const
{
NS_ASSERT (i < GetNMcsSupported (station));
return station->m_state->m_operationalMcsSet[i];
}
+uint32_t
+WifiRemoteStationManager::GetChannelWidth (const WifiRemoteStation *station) const
+{
+ return station->m_state->m_channelWidth;
+}
+
bool
WifiRemoteStationManager::GetShortGuardInterval (const WifiRemoteStation *station) const
{
--- a/src/wifi/model/wifi-remote-station-manager.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-remote-station-manager.h Thu Sep 03 22:16:49 2015 +0200
@@ -31,6 +31,7 @@
#include "wifi-mode.h"
#include "wifi-tx-vector.h"
#include "ht-capabilities.h"
+#include "vht-capabilities.h"
namespace ns3 {
@@ -169,6 +170,13 @@
*/
void AddStationHtCapabilities (Mac48Address from, HtCapabilities htcapabilities);
/**
+ * Records VHT capabilities of the remote station.
+ *
+ * \param from the address of the station being recorded
+ * \param vhtcapabilities the VHT capabilities of the station
+ */
+ void AddStationVhtCapabilities (Mac48Address from,VhtCapabilities vhtcapabilities);
+ /**
* Enable or disable HT capability support.
*
* \param enable enable or disable HT capability support
@@ -180,6 +188,18 @@
* \return true if HT capability support is enabled, false otherwise
*/
bool HasHtSupported (void) const;
+ /**
+ * Enable or disable VHT capability support.
+ *
+ * \param enable enable or disable VHT capability support
+ */
+ void SetVhtSupported (bool enable);
+ /**
+ * Return whether the device has VHT capability support enabled.
+ *
+ * \return true if VHT capability support is enabled, false otherwise
+ */
+ bool HasVhtSupported (void) const;
/**
* Reset the station, invoked in a STA upon dis-association or in an AP upon reboot.
@@ -227,15 +247,15 @@
* Add a given Modulation and Coding Scheme (MCS) index to
* the set of basic MCS.
*
- * \param mcs the MCS index
+ * \param mcs the WifiMode to be added to the basic MCS set
*/
- void AddBasicMcs (uint8_t mcs);
+ void AddBasicMcs (WifiMode mcs);
/**
* Return the default Modulation and Coding Scheme (MCS) index.
*
- * \return the default MCS index
+ * \return the default WifiMode
*/
- uint8_t GetDefaultMcs (void) const;
+ WifiMode GetDefaultMcs (void) const;
/**
* Return the number of basic MCS index.
*
@@ -247,16 +267,16 @@
*
* \param i the position in the list
*
- * \return the MCS at the given list index
+ * \return the basic mcs at the given list index
*/
- uint8_t GetBasicMcs (uint32_t i) const;
+ WifiMode GetBasicMcs (uint32_t i) const;
/**
* Record the MCS index supported by the station.
*
* \param address the address of the station
- * \param mcs the MCS index
+ * \param mcs the WifiMode supported by the station
*/
- void AddSupportedMcs (Mac48Address address, uint8_t mcs);
+ void AddSupportedMcs (Mac48Address address, WifiMode mcs);
/**
* Return a mode for non-unicast packets.
@@ -600,8 +620,7 @@
* \param [in] power The new power.
* \param [in] address The remote station MAC address.
*/
- typedef void (*PowerChangeTracedCallback)
- (uint8_t power, Mac48Address remoteAddress);
+ typedef void (*PowerChangeTracedCallback)(uint8_t power, Mac48Address remoteAddress);
/**
* TracedCallback signature for rate change events.
@@ -609,8 +628,7 @@
* \param [in] rate The new rate.
* \param [in] address The remote station MAC address.
*/
- typedef void (*RateChangeTracedCallback)
- (uint32_t rate, Mac48Address remoteAddress);
+ typedef void (*RateChangeTracedCallback)(uint32_t rate, Mac48Address remoteAddress);
@@ -634,14 +652,14 @@
*/
uint32_t GetNSupported (const WifiRemoteStation *station) const;
/**
- * Return the MCS index supported by the specified station at the specified index.
+ * Return the WifiMode supported by the specified station at the specified index.
*
* \param station the station being queried
* \param i the index
*
- * \return the MCS index at the given index of the specified station
+ * \return the WifiMode at the given index of the specified station
*/
- uint8_t GetMcsSupported (const WifiRemoteStation *station, uint32_t i) const;
+ WifiMode GetMcsSupported (const WifiRemoteStation *station, uint32_t i) const;
/**
* Return the number of MCS supported by the given station.
*
@@ -651,6 +669,14 @@
*/
uint32_t GetNMcsSupported (const WifiRemoteStation *station) const;
/**
+ * Return the channel width supported by the station.
+ *
+ * \param station the station being queried
+ *
+ * \return the channel width (in MHz) supported by the station
+ */
+ uint32_t GetChannelWidth (const WifiRemoteStation *station) const;
+ /**
* Return whether the given station supports short guard interval.
*
* \param station the station being queried
@@ -847,15 +873,17 @@
*/
virtual uint8_t DoGetBlockAckTxPowerLevel (Mac48Address address, WifiMode blockAckMode);
+ virtual uint32_t DoGetCtsTxChannelWidth (Mac48Address address, WifiMode ctsMode);
virtual bool DoGetCtsTxGuardInterval (Mac48Address address, WifiMode ctsMode);
-
virtual uint8_t DoGetCtsTxNss (Mac48Address address, WifiMode ctsMode);
virtual uint8_t DoGetCtsTxNess (Mac48Address address, WifiMode ctsMode);
virtual bool DoGetCtsTxStbc (Mac48Address address, WifiMode ctsMode);
+ virtual uint32_t DoGetAckTxChannelWidth (Mac48Address address, WifiMode ctsMode);
virtual bool DoGetAckTxGuardInterval (Mac48Address address, WifiMode ackMode);
virtual uint8_t DoGetAckTxNss (Mac48Address address, WifiMode ackMode);
virtual uint8_t DoGetAckTxNess (Mac48Address address, WifiMode ackMode);
virtual bool DoGetAckTxStbc (Mac48Address address, WifiMode ackMode);
+ virtual uint32_t DoGetBlockAckTxChannelWidth (Mac48Address address, WifiMode ctsMode);
virtual bool DoGetBlockAckTxGuardInterval (Mac48Address address, WifiMode blockAckMode);
virtual uint8_t DoGetBlockAckTxNss (Mac48Address address, WifiMode blockAckMode);
virtual uint8_t DoGetBlockAckTxNess (Mac48Address address, WifiMode blockAckMode);
@@ -1011,15 +1039,16 @@
* WifiRemoteStationManager::GetBasicMode().
*/
WifiModeList m_bssBasicRateSet;
- WifiMcsList m_bssBasicMcsSet;
+ WifiModeList m_bssBasicMcsSet;
StationStates m_states; //!< States of known stations
Stations m_stations; //!< Information for each known stations
WifiMode m_defaultTxMode; //!< The default transmission mode
- uint8_t m_defaultTxMcs; //!< The default transmission modulation-coding scheme (MCS)
+ WifiMode m_defaultTxMcs; //!< The default transmission modulation-coding scheme (MCS)
bool m_htSupported; //!< Flag if HT capability is supported
+ bool m_vhtSupported; //!< Flag if VHT capability is supported
uint32_t m_maxSsrc; //!< Maximum STA short retry count (SSRC)
uint32_t m_maxSlrc; //!< Maximum STA long retry count (SLRC)
uint32_t m_rtsCtsThreshold; //!< Threshold for RTS/CTS
@@ -1074,10 +1103,11 @@
* WifiRemoteStationManager::GetSupported().
*/
WifiModeList m_operationalRateSet;
- WifiMcsList m_operationalMcsSet;
+ WifiModeList m_operationalMcsSet;
Mac48Address m_address; //!< Mac48Address of the remote station
WifiRemoteStationInfo m_info;
+ uint32_t m_channelWidth; //!< Channel width (in MHz) supported by the remote station
bool m_shortGuardInterval; //!< Flag if short guard interval is supported by the remote station
uint32_t m_rx; //!< Number of RX antennas of the remote station
uint32_t m_tx; //!< Number of TX antennas of the remote station
--- a/src/wifi/model/wifi-tx-vector.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-tx-vector.cc Thu Sep 03 22:16:49 2015 +0200
@@ -26,6 +26,7 @@
WifiTxVector::WifiTxVector ()
: m_retries (0),
+ m_channelWidth (20),
m_shortGuardInterval (false),
m_nss (1),
m_ness (0),
@@ -38,10 +39,11 @@
WifiTxVector::WifiTxVector (WifiMode mode, uint8_t powerLevel, uint8_t retries,
bool shortGuardInterval, uint8_t nss, uint8_t ness,
- bool aggregation, bool stbc)
+ uint32_t channelWidth, bool aggregation, bool stbc)
: m_mode (mode),
m_txPowerLevel (powerLevel),
m_retries (retries),
+ m_channelWidth (channelWidth),
m_shortGuardInterval (shortGuardInterval),
m_nss (nss),
m_ness (ness),
@@ -78,6 +80,12 @@
return m_retries;
}
+uint32_t
+WifiTxVector::GetChannelWidth (void) const
+{
+ return m_channelWidth;
+}
+
bool
WifiTxVector::IsShortGuardInterval (void) const
{
@@ -129,6 +137,12 @@
}
void
+WifiTxVector::SetChannelWidth (uint32_t channelWidth)
+{
+ m_channelWidth = channelWidth;
+}
+
+void
WifiTxVector::SetShortGuardInterval (bool guardinterval)
{
m_shortGuardInterval = guardinterval;
@@ -163,6 +177,7 @@
os << "mode: " << v.GetMode () <<
" txpwrlvl: " << (uint32_t)v.GetTxPowerLevel () <<
" retries: " << (uint32_t)v.GetRetries () <<
+ " channel width: " << v.GetChannelWidth () <<
" Short GI: " << v.IsShortGuardInterval () <<
" Nss: " << (uint32_t)v.GetNss () <<
" Ness: " << (uint32_t)v.GetNess () <<
--- a/src/wifi/model/wifi-tx-vector.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/wifi-tx-vector.h Thu Sep 03 22:16:49 2015 +0200
@@ -71,6 +71,7 @@
* \param shortGuardInterval enable or disable short guard interval
* \param nss the number of spatial STBC streams (NSS)
* \param ness the number of extension spatial streams (NESS)
+ * \param channelWidth the channel width in MHz
* \param aggregation enable or disable MPDU aggregation
* \param stbc enable or disable STBC
*/
@@ -80,6 +81,7 @@
bool shortGuardInterval,
uint8_t nss,
uint8_t ness,
+ uint32_t channelWidth,
bool aggregation,
bool stbc);
/**
@@ -113,6 +115,16 @@
*/
void SetRetries (uint8_t retries);
/**
+ * \returns the channel width (in MHz)
+ */
+ uint32_t GetChannelWidth (void) const;
+ /**
+ * Sets the selected channelWidth (in MHz)
+ *
+ * \param channelWidth
+ */
+ void SetChannelWidth (uint32_t channelWidth);
+ /**
* \returns if ShortGuardInterval is used or not
*/
bool IsShortGuardInterval (void) const;
@@ -178,7 +190,7 @@
to PMD_TXPWRLVL.request */
uint8_t m_retries; /**< The DATA_RETRIES/RTS_RETRIES parameter
for Click radiotap information */
-
+ uint32_t m_channelWidth; /**< channel width in MHz */
bool m_shortGuardInterval; /**< true if short GI is going to be used */
uint8_t m_nss; /**< number of streams */
uint8_t m_ness; /**< number of streams in beamforming */
@@ -187,7 +199,6 @@
bool m_modeInitialized; //*< Internal initialization flag */
bool m_txPowerLevelInitialized; //*< Internal initialization flag */
-
};
/**
--- a/src/wifi/model/yans-error-rate-model.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/yans-error-rate-model.cc Thu Sep 03 22:16:49 2015 +0200
@@ -180,20 +180,21 @@
}
double
-YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
+YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const
{
if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM
|| mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
- || mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
+ || mode.GetModulationClass () == WIFI_MOD_CLASS_HT
+ || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
{
- if (mode.GetConstellationSize () == 2)
+ if (mode.GetConstellationSize (1) == 2)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
{
return GetFecBpskBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
10, //dFree
11); //adFree
}
@@ -201,20 +202,20 @@
{
return GetFecBpskBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
5, //dFree
8); //adFree
}
}
- else if (mode.GetConstellationSize () == 4)
+ else if (mode.GetConstellationSize (1) == 4)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
{
return GetFecQamBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
4, //m
10, //dFree
11, //adFree
@@ -224,22 +225,22 @@
{
return GetFecQamBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
4, //m
5, //dFree
8, //adFree
31); //adFreePlusOne
}
}
- else if (mode.GetConstellationSize () == 16)
+ else if (mode.GetConstellationSize (1) == 16)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_1_2)
{
return GetFecQamBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
16, //m
10, //dFree
11, //adFree
@@ -249,34 +250,34 @@
{
return GetFecQamBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
16, //m
5, //dFree
8, //adFree
31); //adFreePlusOne
}
}
- else if (mode.GetConstellationSize () == 64)
+ else if (mode.GetConstellationSize (1) == 64)
{
- if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_2_3)
{
return GetFecQamBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
64, //m
6, //dFree
1, //adFree
16); //adFreePlusOne
}
- if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_5_6)
{
//Table B.32 in Pâl Frenger et al., "Multi-rate Convolutional Codes".
return GetFecQamBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
64, //m
4, //dFree
14, //adFree
@@ -286,18 +287,45 @@
{
return GetFecQamBer (snr,
nbits,
- mode.GetBandwidth (), //signal spread
- mode.GetPhyRate (), //phy rate
+ txVector.GetChannelWidth () * 1000000, //signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), //phy rate
64, //m
5, //dFree
8, //adFree
31); //adFreePlusOne
}
}
+ else if (mode.GetConstellationSize (1) == 256)
+ {
+ if (mode.GetCodeRate (1) == WIFI_CODE_RATE_5_6)
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ txVector.GetChannelWidth () * 1000000, // signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), // phy rate
+ 256, // m
+ 4, // dFree
+ 14, // adFree
+ 69 // adFreePlusOne
+ );
+ }
+ else
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ txVector.GetChannelWidth () * 1000000, // signal spread
+ mode.GetPhyRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), // phy rate
+ 256, // m
+ 5, // dFree
+ 8, // adFree
+ 31 // adFreePlusOne
+ );
+ }
+ }
}
- else if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS)
+ else if (mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS || mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)
{
- switch (mode.GetDataRate ())
+ switch (mode.GetDataRate (20, 0, 1))
{
case 1000000:
return DsssErrorRateModel::GetDsssDbpskSuccessRate (snr, nbits);
@@ -307,6 +335,8 @@
return DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (snr, nbits);
case 11000000:
return DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (snr, nbits);
+ default:
+ NS_ASSERT ("undefined DSSS/HR-DSSS datarate");
}
}
return 0;
--- a/src/wifi/model/yans-error-rate-model.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/yans-error-rate-model.h Thu Sep 03 22:16:49 2015 +0200
@@ -60,7 +60,7 @@
YansErrorRateModel ();
- virtual double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
+ virtual double GetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint32_t nbits) const;
private:
--- a/src/wifi/model/yans-wifi-phy.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/yans-wifi-phy.cc Thu Sep 03 22:16:49 2015 +0200
@@ -17,6 +17,7 @@
*
* Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Ghada Badawy <gbadawy@gmail.com>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include "yans-wifi-phy.h"
@@ -166,12 +167,12 @@
MakeBooleanAccessor (&YansWifiPhy::GetGreenfield,
&YansWifiPhy::SetGreenfield),
MakeBooleanChecker ())
- .AddAttribute ("ChannelBonding",
- "Whether 20MHz or 40MHz.",
- BooleanValue (false),
- MakeBooleanAccessor (&YansWifiPhy::GetChannelBonding,
- &YansWifiPhy::SetChannelBonding),
- MakeBooleanChecker ())
+ .AddAttribute ("ChannelWidth",
+ "Whether 5MHz, 10MHz, 20MHz, 22MHz, 40MHz, 80 MHz or 160 MHz.",
+ UintegerValue (20),
+ MakeUintegerAccessor (&YansWifiPhy::GetChannelWidth,
+ &YansWifiPhy::SetChannelWidth),
+ MakeUintegerChecker<uint32_t> ())
;
return tid;
}
@@ -246,6 +247,9 @@
m_channelStartingFrequency = 5e3;
Configure80211n ();
break;
+ case WIFI_PHY_STANDARD_80211ac:
+ Configure80211ac ();
+ break;
default:
NS_ASSERT (false);
break;
@@ -728,23 +732,23 @@
struct InterferenceHelper::SnrPer snrPer;
snrPer = m_interference.CalculatePlcpHeaderSnrPer (event);
- NS_LOG_DEBUG ("snr(dB)=" << RatioToDb(snrPer.snr) << ", per=" << snrPer.per);
+ NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
- if (m_random->GetValue () > snrPer.per) //plcp reception succeeded
+ if (m_random->GetValue () > snrPer.per) //plcp reception succeeded
{
if (IsModeSupported (txMode) || IsMcsSupported (txMode))
{
- NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
+ NS_LOG_DEBUG ("receiving plcp payload"); //endReceive is already scheduled
m_plcpSuccess = true;
}
- else //mode is not allowed
+ else //mode is not allowed
{
NS_LOG_DEBUG ("drop packet because it was sent using an unsupported mode (" << txMode << ")");
NotifyRxDrop (packet);
m_plcpSuccess = false;
}
}
- else //plcp reception failed
+ else //plcp reception failed
{
NS_LOG_DEBUG ("drop packet because plcp preamble/header reception failed");
NotifyRxDrop (packet);
@@ -755,7 +759,7 @@
void
YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType, uint32_t mpduReferenceNumber)
{
- NS_LOG_FUNCTION (this << packet << txVector.GetMode () << preamble << (uint32_t)txVector.GetTxPowerLevel () << (uint32_t)packetType);
+ NS_LOG_FUNCTION (this << packet << txVector.GetMode () << txVector.GetMode ().GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1) << preamble << (uint32_t)txVector.GetTxPowerLevel () << (uint32_t)packetType);
/* Transmission can happen if:
* - we are syncing on a packet. It is the responsability of the
* MAC layer to avoid doing this but the PHY does nothing to
@@ -782,13 +786,13 @@
}
NotifyTxBegin (packet);
uint32_t dataRate500KbpsUnits;
- if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT)
+ if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT || txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT)
{
- dataRate500KbpsUnits = 128 + WifiModeToMcs (txVector.GetMode ());
+ dataRate500KbpsUnits = 128 + txVector.GetMode ().GetMcsValue ();
}
else
{
- dataRate500KbpsUnits = txVector.GetMode ().GetDataRate () * txVector.GetNss () / 500000;
+ dataRate500KbpsUnits = txVector.GetMode ().GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1) * txVector.GetNss () / 500000;
}
struct mpduInfo aMpdu;
aMpdu.packetType = packetType;
@@ -823,11 +827,11 @@
return false;
}
bool
-YansWifiPhy::IsMcsSupported (WifiMode mode)
+YansWifiPhy::IsMcsSupported (WifiMode mcs)
{
for (uint32_t i = 0; i < GetNMcs (); i++)
{
- if (mode == McsToWifiMode (GetMcs (i)))
+ if (mcs == GetMcs (i))
{
return true;
}
@@ -846,6 +850,7 @@
{
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; //5.000 GHz
+ SetChannelWidth (20); //20 MHz
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6Mbps ());
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate9Mbps ());
@@ -862,6 +867,7 @@
{
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 2407; //2.407 GHz
+ SetChannelWidth (22); //22 MHz
m_deviceRateSet.push_back (WifiPhy::GetDsssRate1Mbps ());
m_deviceRateSet.push_back (WifiPhy::GetDsssRate2Mbps ());
@@ -874,6 +880,7 @@
{
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 2407; //2.407 GHz
+ SetChannelWidth (20); //20 MHz
m_deviceRateSet.push_back (WifiPhy::GetDsssRate1Mbps ());
m_deviceRateSet.push_back (WifiPhy::GetDsssRate2Mbps ());
@@ -894,6 +901,7 @@
{
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; //5.000 GHz, suppose 802.11a
+ SetChannelWidth (10); //10 MHz
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate3MbpsBW10MHz ());
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate4_5MbpsBW10MHz ());
@@ -910,6 +918,7 @@
{
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; //5.000 GHz, suppose 802.11a
+ SetChannelWidth (5); //5 MHz
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate1_5MbpsBW5MHz ());
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate2_25MbpsBW5MHz ());
@@ -926,6 +935,8 @@
{
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; //5.000 GHz
+ SetChannelWidth (20); //20 MHz
+
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6Mbps ());
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12Mbps ());
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate18Mbps ());
@@ -937,6 +948,7 @@
YansWifiPhy::Configure80211n (void)
{
NS_LOG_FUNCTION (this);
+ SetChannelWidth (20); //20 MHz
if (m_channelStartingFrequency >= 2400 && m_channelStartingFrequency <= 2500) //at 2.4 GHz
{
m_deviceRateSet.push_back (WifiPhy::GetDsssRate1Mbps ());
@@ -953,11 +965,51 @@
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12Mbps ());
m_deviceRateSet.push_back (WifiPhy::GetOfdmRate24Mbps ());
}
+
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs0 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs1 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs2 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs3 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs4 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs5 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs6 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs7 ());
+
m_bssMembershipSelectorSet.push_back (HT_PHY);
- for (uint8_t i = 0; i < 8; i++)
- {
- m_deviceMcsSet.push_back (i);
- }
+}
+
+void
+YansWifiPhy::Configure80211ac (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_channelStartingFrequency = 5e3; //5.000 GHz
+ SetChannelWidth (80); //80 MHz
+
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate24Mbps ());
+
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs0 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs1 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs2 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs3 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs4 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs5 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs6 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetHtMcs7 ());
+
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs0 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs1 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs2 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs3 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs4 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs5 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs6 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs7 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs8 ());
+ m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs9 ());
+
+ m_bssMembershipSelectorSet.push_back (VHT_PHY);
}
void
@@ -1095,20 +1147,20 @@
if (m_plcpSuccess == true)
{
- NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate ()) <<
- ", snr(dB)=" << RatioToDb(snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
+ NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate (event->GetTxVector ().GetChannelWidth (), event->GetTxVector ().IsShortGuardInterval (), 1)) <<
+ ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
if (m_random->GetValue () > snrPer.per)
{
NotifyRxEnd (packet);
uint32_t dataRate500KbpsUnits;
- if ((event->GetPayloadMode ().GetModulationClass () == WIFI_MOD_CLASS_HT))
+ if ((event->GetPayloadMode ().GetModulationClass () == WIFI_MOD_CLASS_HT) || (event->GetPayloadMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT))
{
- dataRate500KbpsUnits = 128 + WifiModeToMcs (event->GetPayloadMode ());
+ dataRate500KbpsUnits = 128 + event->GetPayloadMode ().GetMcsValue ();
}
else
{
- dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () * event->GetTxVector ().GetNss () / 500000;
+ dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate (event->GetTxVector ().GetChannelWidth (), event->GetTxVector ().IsShortGuardInterval (), 1) * event->GetTxVector ().GetNss () / 500000;
}
struct signalNoiseDbm signalNoise;
signalNoise.signal = RatioToDb (event->GetRxPowerW ()) + 30;
@@ -1125,7 +1177,6 @@
}
else
{
- //notify rx end
m_state->SwitchFromRxEndError (packet, snrPer.snr);
}
@@ -1227,16 +1278,17 @@
return m_greenfield;
}
-bool
-YansWifiPhy::GetChannelBonding (void) const
+void
+YansWifiPhy::SetChannelWidth (uint32_t channelwidth)
{
- return m_channelBonding;
+ NS_ASSERT_MSG (channelwidth == 5 || channelwidth == 10 || channelwidth == 20 || channelwidth == 22 || channelwidth == 40 || channelwidth == 80 || channelwidth == 160, "wrong channel width value");
+ m_channelWidth = channelwidth;
}
-void
-YansWifiPhy::SetChannelBonding (bool channelbonding)
+uint32_t
+YansWifiPhy::GetChannelWidth (void) const
{
- m_channelBonding = channelbonding;
+ return m_channelWidth;
}
uint32_t
@@ -1256,17 +1308,31 @@
{
uint32_t id = GetBssMembershipSelector (selector);
WifiModeList supportedmodes;
- if (id == HT_PHY)
+ if (id == HT_PHY || id == VHT_PHY)
{
//mandatory MCS 0 to 7
- supportedmodes.push_back (WifiPhy::GetOfdmRate6_5MbpsBW20MHz ());
- supportedmodes.push_back (WifiPhy::GetOfdmRate13MbpsBW20MHz ());
- supportedmodes.push_back (WifiPhy::GetOfdmRate19_5MbpsBW20MHz ());
- supportedmodes.push_back (WifiPhy::GetOfdmRate26MbpsBW20MHz ());
- supportedmodes.push_back (WifiPhy::GetOfdmRate39MbpsBW20MHz ());
- supportedmodes.push_back (WifiPhy::GetOfdmRate52MbpsBW20MHz ());
- supportedmodes.push_back (WifiPhy::GetOfdmRate58_5MbpsBW20MHz ());
- supportedmodes.push_back (WifiPhy::GetOfdmRate65MbpsBW20MHz ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs0 ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs1 ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs2 ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs3 ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs4 ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs5 ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs6 ());
+ supportedmodes.push_back (WifiPhy::GetHtMcs7 ());
+ }
+ if (id == VHT_PHY)
+ {
+ //mandatory MCS 0 to 9
+ supportedmodes.push_back (WifiPhy::GetVhtMcs0 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs1 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs2 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs3 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs4 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs5 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs6 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs7 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs8 ());
+ supportedmodes.push_back (WifiPhy::GetVhtMcs9 ());
}
return supportedmodes;
}
@@ -1277,228 +1343,10 @@
return m_deviceMcsSet.size ();
}
-uint8_t
+WifiMode
YansWifiPhy::GetMcs (uint8_t mcs) const
{
return m_deviceMcsSet[mcs];
}
-uint32_t
-YansWifiPhy::WifiModeToMcs (WifiMode mode)
-{
- uint32_t mcs = 0;
- if (mode.GetUniqueName () == "OfdmRate135MbpsBW40MHzShGi" || mode.GetUniqueName () == "OfdmRate65MbpsBW20MHzShGi")
- {
- mcs = 6;
- }
- else
- {
- switch (mode.GetDataRate ())
- {
- case 6500000:
- case 7200000:
- case 13500000:
- case 15000000:
- mcs = 0;
- break;
- case 13000000:
- case 14400000:
- case 27000000:
- case 30000000:
- mcs = 1;
- break;
- case 19500000:
- case 21700000:
- case 40500000:
- case 45000000:
- mcs = 2;
- break;
- case 26000000:
- case 28900000:
- case 54000000:
- case 60000000:
- mcs = 3;
- break;
- case 39000000:
- case 43300000:
- case 81000000:
- case 90000000:
- mcs = 4;
- break;
- case 52000000:
- case 57800000:
- case 108000000:
- case 120000000:
- mcs = 5;
- break;
- case 58500000:
- case 121500000:
- mcs = 6;
- break;
- case 65000000:
- case 72200000:
- case 135000000:
- case 150000000:
- mcs = 7;
- break;
- }
- }
- return mcs;
-}
-
-WifiMode
-YansWifiPhy::McsToWifiMode (uint8_t mcs)
-{
- WifiMode mode;
- switch (mcs)
- {
- case 7:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate65MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate72_2MbpsBW20MHz ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate135MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate150MbpsBW40MHz ();
- }
- break;
- case 6:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate58_5MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate65MbpsBW20MHzShGi ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate121_5MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate135MbpsBW40MHzShGi ();
- }
- break;
- case 5:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate52MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate57_8MbpsBW20MHz ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate108MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate120MbpsBW40MHz ();
- }
- break;
- case 4:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate39MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate43_3MbpsBW20MHz ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate81MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate90MbpsBW40MHz ();
- }
- break;
- case 3:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate26MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate28_9MbpsBW20MHz ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate54MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate60MbpsBW40MHz ();
- }
- break;
- case 2:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate19_5MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate21_7MbpsBW20MHz ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate40_5MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate45MbpsBW40MHz ();
- }
- break;
- case 1:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate13MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate14_4MbpsBW20MHz ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate27MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate30MbpsBW40MHz ();
- }
- break;
- case 0:
- default:
- if (!GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate6_5MbpsBW20MHz ();
- }
- else if (GetGuardInterval () && !GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate7_2MbpsBW20MHz ();
- }
- else if (!GetGuardInterval () && GetChannelBonding ())
- {
- mode = WifiPhy::GetOfdmRate13_5MbpsBW40MHz ();
- }
- else
- {
- mode = WifiPhy::GetOfdmRate15MbpsBW40MHz ();
- }
- break;
- }
- return mode;
-}
-
} //namespace ns3
--- a/src/wifi/model/yans-wifi-phy.h Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/model/yans-wifi-phy.h Thu Sep 03 22:16:49 2015 +0200
@@ -17,6 +17,7 @@
*
* Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Ghada Badawy <gbadawy@gmail.com>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#ifndef YANS_WIFI_PHY_H
@@ -40,6 +41,7 @@
namespace ns3 {
+#define VHT_PHY 126
#define HT_PHY 127
class YansWifiChannel;
@@ -297,7 +299,7 @@
virtual uint32_t GetNModes (void) const;
virtual WifiMode GetMode (uint32_t mode) const;
virtual bool IsModeSupported (WifiMode mode) const;
- virtual bool IsMcsSupported (WifiMode mode);
+ virtual bool IsMcsSupported (WifiMode mcs);
virtual double CalculateSnr (WifiMode txMode, double ber) const;
virtual Ptr<WifiChannel> GetChannel (void) const;
@@ -385,17 +387,17 @@
*/
virtual bool GetGreenfield (void) const;
/**
- * Return whether channel bonding is supported.
+ * Return channel width.
*
- * \return true if channel bonding is supported, false otherwise
+ * \return channel width
*/
- virtual bool GetChannelBonding (void) const;
+ virtual uint32_t GetChannelWidth (void) const;
/**
- * Enable or disable channel bonding support.
+ * Set channel width.
*
- * \param channelbonding Enable or disable channel bonding
+ * \param channel width
*/
- virtual void SetChannelBonding (bool channelbonding);
+ virtual void SetChannelWidth (uint32_t channelwidth);
virtual uint32_t GetNBssMembershipSelectors (void) const;
virtual uint32_t GetBssMembershipSelector (uint32_t selector) const;
@@ -405,11 +407,7 @@
* \return the number of MCS supported by this phy
*/
virtual uint8_t GetNMcs (void) const;
- virtual uint8_t GetMcs (uint8_t mcs) const;
-
- virtual uint32_t WifiModeToMcs (WifiMode mode);
- virtual WifiMode McsToWifiMode (uint8_t mcs);
-
+ virtual WifiMode GetMcs (uint8_t mcs) const;
private:
virtual void DoInitialize (void);
@@ -447,6 +445,11 @@
*/
void Configure80211n (void);
/**
+ * Configure YansWifiPhy with appropriate channel frequency and
+ * supported rates for 802.11ac standard.
+ */
+ void Configure80211ac (void);
+ /**
* Return the energy detection threshold.
*
* \return the energy detection threshold.
@@ -524,7 +527,7 @@
bool m_stbc; //!< Flag if STBC is used
bool m_greenfield; //!< Flag if GreenField format is supported
bool m_guardInterval; //!< Flag if short guard interval is used
- bool m_channelBonding; //!< Flag if channel bonding is used
+ uint32_t m_channelWidth; //!< Channel width
/**
@@ -564,9 +567,9 @@
* mandatory rates".
*/
WifiModeList m_deviceRateSet;
+ WifiModeList m_deviceMcsSet;
std::vector<uint32_t> m_bssMembershipSelectorSet;
- std::vector<uint8_t> m_deviceMcsSet;
EventId m_endRxEvent;
EventId m_endPlcpRxEvent;
--- a/src/wifi/test/power-rate-adaptation-test.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/test/power-rate-adaptation-test.cc Thu Sep 03 22:16:49 2015 +0200
@@ -154,7 +154,7 @@
WifiMode mode = txVector.GetMode ();
int power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Initial data rate wrong");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Initial data rate wrong");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Initial power level wrong");
//-----------------------------------------------------------------------------------------------------
@@ -172,7 +172,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 16, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -187,7 +187,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -207,7 +207,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 16, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -222,7 +222,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -238,7 +238,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 48000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 48000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -256,7 +256,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -271,7 +271,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 48000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 48000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -289,7 +289,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -307,7 +307,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 16, "PARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -327,7 +327,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "PARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "PARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "PARF: Incorrect value of power level");
Simulator::Stop (Seconds (10.0));
@@ -378,7 +378,7 @@
WifiMode mode = txVector.GetMode ();
int power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Initial data rate wrong");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Initial data rate wrong");
NS_TEST_ASSERT_MSG_EQ (power, 17, "APARF: Initial power level wrong");
//-----------------------------------------------------------------------------------------------------
@@ -397,7 +397,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 16, "APARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -412,7 +412,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "APARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -431,7 +431,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 16, "APARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -450,7 +450,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 15, "APARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -468,7 +468,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 0, "APARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -483,7 +483,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 1, "Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -501,7 +501,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "APARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -517,7 +517,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 48000000, "Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 48000000, "Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -535,7 +535,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 48000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 48000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 16, "APARF: Incorrect value of power level");
//-----------------------------------------------------------------------------------------------------
@@ -555,7 +555,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 48000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 48000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 7, "APARF: Incorrect value of power level");
for (int i = 0; i < 3; i++)
@@ -567,7 +567,7 @@
mode = txVector.GetMode ();
power = (int) txVector.GetTxPowerLevel ();
- NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (), 54000000, "APARF: Incorrect vale of data rate");
+ NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1), 54000000, "APARF: Incorrect vale of data rate");
NS_TEST_ASSERT_MSG_EQ (power, 17, "APARF: Incorrect value of power level");
Simulator::Stop (Seconds (10.0));
--- a/src/wifi/test/tx-duration-test.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/test/tx-duration-test.cc Thu Sep 03 22:16:49 2015 +0200
@@ -15,7 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: Nicola Baldo <nbaldo@cttc.es>
+ * Authors: Nicola Baldo <nbaldo@cttc.es>
+ * Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include <ns3/object.h>
@@ -47,11 +48,13 @@
*
* @param size size of payload in octets (includes everything after the PLCP header)
* @param payloadMode the WifiMode used
+ * @param channelWidth the channel width used (in MHz)
+ * @param isShortGuardInterval whether short guard interval is used
* @param knownDurationMicroSeconds the known duration value of the transmission in microseconds
*
* @return true if values correspond, false otherwise
*/
- bool CheckPayloadDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, uint32_t knownDurationMicroSeconds);
+ bool CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint32_t channelWidth, bool isShortGuardInterval, WifiPreamble preamble, uint32_t knownDurationMicroSeconds);
/**
* Check if the overall tx duration returned by InterferenceHelper
@@ -59,12 +62,14 @@
*
* @param size size of payload in octets (includes everything after the PLCP header)
* @param payloadMode the WifiMode used
+ * @param channelWidth the channel width used (in MHz)
+ * @param isShortGuardInterval whether short guard interval is used
* @param preamble the WifiPreamble used
* @param knownDurationMicroSeconds the known duration value of the transmission in microseconds
*
* @return true if values correspond, false otherwise
*/
- bool CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, double knownDurationMicroSeconds);
+ bool CheckTxDuration (uint32_t size, WifiMode payloadMode, uint32_t channelWidth, bool isShortGuardInterval, WifiPreamble preamble, double knownDurationMicroSeconds);
};
@@ -78,22 +83,29 @@
}
bool
-TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, uint32_t knownDurationMicroSeconds)
+TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint32_t channelWidth, bool isShortGuardInterval, WifiPreamble preamble, uint32_t knownDurationMicroSeconds)
{
WifiTxVector txVector;
txVector.SetMode (payloadMode);
+ txVector.SetChannelWidth (channelWidth);
+ txVector.SetShortGuardInterval (isShortGuardInterval);
+ txVector.SetNss (1);
+ txVector.SetStbc (0);
+ txVector.SetNess (0);
double testedFrequency = CHANNEL_1_MHZ;
Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
- || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
+ || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT
+ || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
{
testedFrequency = CHANNEL_36_MHZ;
}
- double calculatedDurationMicroSeconds = (double)phy->GetPayloadDuration (size, txVector, preamble, testedFrequency, 0, 0).GetMicroSeconds ();
+ double calculatedDurationMicroSeconds = (double)phy->GetPayloadDuration (size, txVector, preamble, testedFrequency, 0, 0).GetMicroSeconds ();
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
+ << " datarate=" << payloadMode.GetDataRate (channelWidth, isShortGuardInterval, 1)
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
<< std::endl;
@@ -108,6 +120,7 @@
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
+ << " datarate=" << payloadMode.GetDataRate (channelWidth, isShortGuardInterval, 1)
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
<< std::endl;
@@ -118,17 +131,20 @@
}
bool
-TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, double knownDurationMicroSeconds)
+TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, uint32_t channelWidth, bool isShortGuardInterval, WifiPreamble preamble, double knownDurationMicroSeconds)
{
WifiTxVector txVector;
txVector.SetMode (payloadMode);
+ txVector.SetChannelWidth (channelWidth);
+ txVector.SetShortGuardInterval (isShortGuardInterval);
txVector.SetNss (1);
txVector.SetStbc (0);
txVector.SetNess (0);
double testedFrequency = CHANNEL_1_MHZ;
Ptr<YansWifiPhy> phy = CreateObject<YansWifiPhy> ();
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
- || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
+ || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT
+ || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
{
testedFrequency = CHANNEL_36_MHZ;
}
@@ -137,6 +153,7 @@
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
+ << " datarate=" << payloadMode.GetDataRate (channelWidth, isShortGuardInterval, 1)
<< " preamble=" << preamble
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
@@ -152,6 +169,7 @@
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
+ << " datarate=" << payloadMode.GetDataRate (channelWidth, isShortGuardInterval, 1)
<< " preamble=" << preamble
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
@@ -169,10 +187,10 @@
//IEEE Std 802.11-2007 Table 18-2 "Example of LENGTH calculations for CCK"
retval = retval
- && CheckPayloadDuration (1023, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 744)
- && CheckPayloadDuration (1024, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 745)
- && CheckPayloadDuration (1025, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 746)
- && CheckPayloadDuration (1026, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 747);
+ && CheckPayloadDuration (1023, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 744)
+ && CheckPayloadDuration (1024, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 745)
+ && CheckPayloadDuration (1025, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 746)
+ && CheckPayloadDuration (1026, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 747);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11b CCK duration failed");
@@ -181,102 +199,137 @@
//The payload durations for modes other than 11mbb have been
//calculated by hand according to IEEE Std 802.11-2007 18.2.3.5
retval = retval
- && CheckTxDuration (1023, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_SHORT, 744 + 96)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_SHORT, 745 + 96)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_SHORT, 746 + 96)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_SHORT, 747 + 96)
- && CheckTxDuration (1023, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 744 + 192)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 745 + 192)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 746 + 192)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 747 + 192)
- && CheckTxDuration (1023, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_SHORT, 1488 + 96)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_SHORT, 1490 + 96)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_SHORT, 1491 + 96)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_SHORT, 1493 + 96)
- && CheckTxDuration (1023, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_LONG, 1488 + 192)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_LONG, 1490 + 192)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_LONG, 1491 + 192)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate5_5Mbps (), WIFI_PREAMBLE_LONG, 1493 + 192)
- && CheckTxDuration (1023, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_SHORT, 4092 + 96)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_SHORT, 4096 + 96)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_SHORT, 4100 + 96)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_SHORT, 4104 + 96)
- && CheckTxDuration (1023, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_LONG, 4092 + 192)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_LONG, 4096 + 192)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_LONG, 4100 + 192)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate2Mbps (), WIFI_PREAMBLE_LONG, 4104 + 192)
- && CheckTxDuration (1023, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_SHORT, 8184 + 96)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_SHORT, 8192 + 96)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_SHORT, 8200 + 96)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_SHORT, 8208 + 96)
- && CheckTxDuration (1023, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 8184 + 192)
- && CheckTxDuration (1024, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 8192 + 192)
- && CheckTxDuration (1025, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 8200 + 192)
- && CheckTxDuration (1026, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 8208 + 192);
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 744 + 96)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 745 + 96)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 746 + 96)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 747 + 96)
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 744 + 192)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 745 + 192)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 746 + 192)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 747 + 192)
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 1488 + 96)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 1490 + 96)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 1491 + 96)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 1493 + 96)
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_LONG, 1488 + 192)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_LONG, 1490 + 192)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_LONG, 1491 + 192)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate5_5Mbps (), 22, false, WIFI_PREAMBLE_LONG, 1493 + 192)
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 4092 + 96)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 4096 + 96)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 4100 + 96)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 4104 + 96)
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_LONG, 4092 + 192)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_LONG, 4096 + 192)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_LONG, 4100 + 192)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate2Mbps (), 22, false, WIFI_PREAMBLE_LONG, 4104 + 192)
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 8184 + 96)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 8192 + 96)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 8200 + 96)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_SHORT, 8208 + 96)
+ && CheckTxDuration (1023, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_LONG, 8184 + 192)
+ && CheckTxDuration (1024, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_LONG, 8192 + 192)
+ && CheckTxDuration (1025, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_LONG, 8200 + 192)
+ && CheckTxDuration (1026, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_LONG, 8208 + 192);
//values from http://mailman.isi.edu/pipermail/ns-developers/2009-July/006226.html
- retval = retval && CheckTxDuration (14, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 304);
-
+ retval = retval && CheckTxDuration (14, WifiPhy::GetDsssRate1Mbps (), 22, false, WIFI_PREAMBLE_LONG, 304);
+
//values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
retval = retval
- && CheckTxDuration (1536, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 1310)
- && CheckTxDuration (76, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 248)
- && CheckTxDuration (14, WifiPhy::GetDsssRate11Mbps (), WIFI_PREAMBLE_LONG, 203);
-
+ && CheckTxDuration (1536, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 1310)
+ && CheckTxDuration (76, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 248)
+ && CheckTxDuration (14, WifiPhy::GetDsssRate11Mbps (), 22, false, WIFI_PREAMBLE_LONG, 203);
+
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11b duration failed");
-
+
//802.11a durations
//values from http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
retval = retval
- && CheckTxDuration (1536, WifiPhy::GetOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 248)
- && CheckTxDuration (76, WifiPhy::GetOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 32)
- && CheckTxDuration (14, WifiPhy::GetOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 24);
+ && CheckTxDuration (1536, WifiPhy::GetOfdmRate54Mbps (), 20, false, WIFI_PREAMBLE_LONG, 248)
+ && CheckTxDuration (76, WifiPhy::GetOfdmRate54Mbps (), 20, false, WIFI_PREAMBLE_LONG, 32)
+ && CheckTxDuration (14, WifiPhy::GetOfdmRate54Mbps (), 20, false, WIFI_PREAMBLE_LONG, 24);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11a duration failed");
//802.11g durations are same as 802.11a durations but with 6 us signal extension
retval = retval
- && CheckTxDuration (1536, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 254)
- && CheckTxDuration (76, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 38)
- && CheckTxDuration (14, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 30);
+ && CheckTxDuration (1536, WifiPhy::GetErpOfdmRate54Mbps (), 20, false, WIFI_PREAMBLE_LONG, 254)
+ && CheckTxDuration (76, WifiPhy::GetErpOfdmRate54Mbps (), 20, false, WIFI_PREAMBLE_LONG, 38)
+ && CheckTxDuration (14, WifiPhy::GetErpOfdmRate54Mbps (), 20, false, WIFI_PREAMBLE_LONG, 30);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11g duration failed");
//802.11n durations
retval = retval
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF, 228)
- && CheckTxDuration (76, WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF, 48)
- && CheckTxDuration (14, WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF, 40)
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_GF, 220)
- && CheckTxDuration (76, WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_GF, 40)
- && CheckTxDuration (14, WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_GF, 32)
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate7_2MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF, 1746)
- && CheckTxDuration (76, WifiPhy::GetOfdmRate7_2MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF, 126)
- && CheckTxDuration (14, WifiPhy::GetOfdmRate7_2MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF, 57.6)
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate7_2MbpsBW20MHz (), WIFI_PREAMBLE_HT_GF, 1738)
- && CheckTxDuration (76, WifiPhy::GetOfdmRate7_2MbpsBW20MHz (), WIFI_PREAMBLE_HT_GF, 118)
- && CheckTxDuration (14, WifiPhy::GetOfdmRate7_2MbpsBW20MHz (), WIFI_PREAMBLE_HT_GF, 49.6)
- && CheckTxDuration (1536, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_MF, 226.8)
- && CheckTxDuration (76, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_MF, 46.8)
- && CheckTxDuration (14, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_MF, 39.6)
- && CheckTxDuration (1536, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF, 218.8)
- && CheckTxDuration (76, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF, 38.8)
- && CheckTxDuration (14, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF, 31.6)
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate135MbpsBW40MHz (), WIFI_PREAMBLE_HT_MF, 128)
- && CheckTxDuration (76,WifiPhy::GetOfdmRate135MbpsBW40MHz (), WIFI_PREAMBLE_HT_MF, 44)
- && CheckTxDuration (14,WifiPhy::GetOfdmRate135MbpsBW40MHz (), WIFI_PREAMBLE_HT_MF, 40)
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate135MbpsBW40MHz (), WIFI_PREAMBLE_HT_GF, 120)
- && CheckTxDuration (76,WifiPhy::GetOfdmRate135MbpsBW40MHz (), WIFI_PREAMBLE_HT_GF, 36)
- && CheckTxDuration (14,WifiPhy::GetOfdmRate135MbpsBW40MHz (), WIFI_PREAMBLE_HT_GF, 32)
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate150MbpsBW40MHz (), WIFI_PREAMBLE_HT_MF, 118.8)
- && CheckTxDuration (76,WifiPhy::GetOfdmRate150MbpsBW40MHz (), WIFI_PREAMBLE_HT_MF, 43.2)
- && CheckTxDuration (14,WifiPhy::GetOfdmRate150MbpsBW40MHz (), WIFI_PREAMBLE_HT_MF, 39.6)
- && CheckTxDuration (1536,WifiPhy::GetOfdmRate150MbpsBW40MHz (), WIFI_PREAMBLE_HT_GF, 110.8)
- && CheckTxDuration (76,WifiPhy::GetOfdmRate150MbpsBW40MHz (), WIFI_PREAMBLE_HT_GF, 35.2)
- && CheckTxDuration (14,WifiPhy::GetOfdmRate150MbpsBW40MHz (), WIFI_PREAMBLE_HT_GF, 31.6);
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs7 (), 20, false, WIFI_PREAMBLE_HT_MF, 228)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs7 (), 20, false, WIFI_PREAMBLE_HT_MF, 48)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs7 (), 20, false, WIFI_PREAMBLE_HT_MF, 40)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs7 (), 20, false, WIFI_PREAMBLE_HT_GF, 220)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs7 (), 20, false, WIFI_PREAMBLE_HT_GF, 40)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs7 (), 20, false, WIFI_PREAMBLE_HT_GF, 32)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs0 (), 20, true, WIFI_PREAMBLE_HT_MF, 1742.4)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs0 (), 20, true, WIFI_PREAMBLE_HT_MF, 126)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs0 (), 20, true, WIFI_PREAMBLE_HT_MF, 57.6)
+ && CheckTxDuration (1536,WifiPhy::GetHtMcs0 (), 20, true, WIFI_PREAMBLE_HT_GF, 1734.4)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs0 (), 20, true, WIFI_PREAMBLE_HT_GF, 118)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs0 (), 20, true, WIFI_PREAMBLE_HT_GF, 49.6)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs6 (), 20, true, WIFI_PREAMBLE_HT_MF, 226.8)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs6 (), 20, true, WIFI_PREAMBLE_HT_MF, 46.8)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs6 (), 20, true, WIFI_PREAMBLE_HT_MF, 39.6)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs6 (), 20, true, WIFI_PREAMBLE_HT_GF, 218.8)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs6 (), 20, true, WIFI_PREAMBLE_HT_GF, 38.8)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs6 (), 20, true, WIFI_PREAMBLE_HT_GF, 31.6)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs7 (), 40, false, WIFI_PREAMBLE_HT_MF, 128)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs7 (), 40, false, WIFI_PREAMBLE_HT_MF, 44)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs7 (), 40, false, WIFI_PREAMBLE_HT_MF, 40)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs7 (), 40, false, WIFI_PREAMBLE_HT_GF, 120)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs7 (), 40, false, WIFI_PREAMBLE_HT_GF, 36)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs7 (), 40, false, WIFI_PREAMBLE_HT_GF, 32)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs7 (), 40, true, WIFI_PREAMBLE_HT_MF, 118.8)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs7 (), 40, true, WIFI_PREAMBLE_HT_MF, 43.2)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs7 (), 40, true, WIFI_PREAMBLE_HT_MF, 39.6)
+ && CheckTxDuration (1536, WifiPhy::GetHtMcs7 (), 40, true, WIFI_PREAMBLE_HT_GF, 110.8)
+ && CheckTxDuration (76, WifiPhy::GetHtMcs7 (), 40, true, WIFI_PREAMBLE_HT_GF, 35.2)
+ && CheckTxDuration (14, WifiPhy::GetHtMcs7 (), 40, true, WIFI_PREAMBLE_HT_GF, 31.6);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11n duration failed");
+
+ //802.11ac durations
+ retval = retval
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs8 (), 20, false, WIFI_PREAMBLE_VHT, 200)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs8 (), 20, false, WIFI_PREAMBLE_VHT, 52)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs8 (), 20, false, WIFI_PREAMBLE_VHT, 44)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs8 (), 20, true, WIFI_PREAMBLE_VHT, 184)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs8 (), 20, true, WIFI_PREAMBLE_VHT, 50.8)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs8 (), 20, true, WIFI_PREAMBLE_VHT, 43.6)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs9 (), 40, false, WIFI_PREAMBLE_VHT, 112)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs9 (), 40, false, WIFI_PREAMBLE_VHT, 44)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs9 (), 40, false, WIFI_PREAMBLE_VHT, 44)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs9 (), 40, true, WIFI_PREAMBLE_VHT, 104.8)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs9 (), 40, true, WIFI_PREAMBLE_VHT, 43.6)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs9 (), 40, true, WIFI_PREAMBLE_VHT, 43.6)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs0 (), 80, false, WIFI_PREAMBLE_VHT, 464)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs0 (), 80, false, WIFI_PREAMBLE_VHT, 64)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs0 (), 80, false, WIFI_PREAMBLE_VHT, 48)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs0 (), 80, true, WIFI_PREAMBLE_VHT, 421.6)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs0 (), 80, true, WIFI_PREAMBLE_VHT, 61.6)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs0 (), 80, true, WIFI_PREAMBLE_VHT, 47.2)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs9 (), 80, false, WIFI_PREAMBLE_VHT, 72)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs9 (), 80, false, WIFI_PREAMBLE_VHT, 44)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs9 (), 80, false, WIFI_PREAMBLE_VHT, 44)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs9 (), 80, true, WIFI_PREAMBLE_VHT, 68.8)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs9 (), 80, true, WIFI_PREAMBLE_VHT, 43.6)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs9 (), 80, true, WIFI_PREAMBLE_VHT, 43.6)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs8 (), 160, false, WIFI_PREAMBLE_VHT, 60)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs8 (), 160, false, WIFI_PREAMBLE_VHT, 44)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs8 (), 160, false, WIFI_PREAMBLE_VHT, 44)
+ && CheckTxDuration (1536, WifiPhy::GetVhtMcs8 (), 160, true, WIFI_PREAMBLE_VHT, 58)
+ && CheckTxDuration (76, WifiPhy::GetVhtMcs8 (), 160, true, WIFI_PREAMBLE_VHT, 43.6)
+ && CheckTxDuration (14, WifiPhy::GetVhtMcs8 (), 160, true, WIFI_PREAMBLE_VHT, 43.6);
+
+ NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11ac duration failed");
}
--- a/src/wifi/test/wifi-aggregation-test.cc Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/test/wifi-aggregation-test.cc Thu Sep 03 22:16:49 2015 +0200
@@ -64,7 +64,7 @@
*/
m_factory = ObjectFactory ();
m_factory.SetTypeId ("ns3::ConstantRateWifiManager");
- m_factory.Set ("DataMode", StringValue ("OfdmRate65MbpsBW20MHz"));
+ m_factory.Set ("DataMode", StringValue ("HtMcs7"));
m_manager = m_factory.Create<WifiRemoteStationManager> ();
m_manager->SetupPhy (m_phy);
--- a/src/wifi/wscript Wed Sep 02 16:37:05 2015 -0700
+++ b/src/wifi/wscript Thu Sep 03 22:16:49 2015 +0200
@@ -72,6 +72,8 @@
'model/wifi-radio-energy-model.cc',
'model/wifi-tx-current-model.cc',
'helper/wifi-radio-energy-model-helper.cc',
+ 'model/vht-capabilities.cc',
+ 'helper/vht-wifi-mac-helper.cc',
'helper/ht-wifi-mac-helper.cc',
'helper/athstats-helper.cc',
'helper/wifi-helper.cc',
@@ -161,6 +163,8 @@
'model/wifi-radio-energy-model.h',
'model/wifi-tx-current-model.h',
'helper/wifi-radio-energy-model-helper.h',
+ 'model/vht-capabilities.h',
+ 'helper/vht-wifi-mac-helper.h',
'helper/ht-wifi-mac-helper.h',
'helper/athstats-helper.h',
'helper/wifi-helper.h',