wifi: Extend protection mechanisms to support 802.11n

This commit is contained in:
Sébastien Deronne
2017-02-02 19:04:00 +01:00
parent 908d87fba6
commit f7a898ed10
3 changed files with 130 additions and 53 deletions

View File

@@ -101,39 +101,39 @@ Experiment::Run (bool enableProtection, bool enableShortSlotTime, bool enableSho
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ShortSlotTimeSupported", BooleanValue (enableShortSlotTime));
// Configure the PLCP preamble type: long or short
phy.Set ("ShortPlcpPreambleSupported", BooleanValue (enableShortPlcpPreamble));
NetDeviceContainer bStaDevice;
bStaDevice = wifi.Install (phy, mac, wifiBStaNodes);
// 802.11b/g STA
wifi.SetStandard (WIFI_PHY_STANDARD_80211g);
NetDeviceContainer gStaDevice;
gStaDevice = wifi.Install (phy, mac, wifiGStaNodes);
// 802.11b/g AP
mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid),
"BeaconGeneration", BooleanValue (true),
"EnableNonErpProtection", BooleanValue (enableProtection),
"ShortSlotTimeSupported", BooleanValue (enableShortSlotTime));
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));
if (isMixed)
{
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
}
{
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
}
positionAlloc->Add (Vector (0.0, 5.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (wifiApNode);
@@ -172,11 +172,11 @@ Experiment::Run (bool enableProtection, bool enableShortSlotTime, bool enableSho
ApplicationContainer clientApp = myClient.Install (wifiGStaNodes);
clientApp.Start (Seconds (1.0));
clientApp.Stop (Seconds (simulationTime + 1));
Simulator::Stop (Seconds (simulationTime + 1));
Simulator::Run ();
Simulator::Destroy ();
totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0);
}
@@ -185,7 +185,7 @@ Experiment::Run (bool enableProtection, bool enableShortSlotTime, bool enableSho
uint16_t port = 50000;
Address apLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", apLocalAddress);
ApplicationContainer sinkApp = packetSinkHelper.Install (wifiApNode.Get (0));
sinkApp.Start (Seconds (0.0));
sinkApp.Stop (Seconds (simulationTime + 1));
@@ -195,10 +195,10 @@ Experiment::Run (bool enableProtection, bool enableShortSlotTime, bool enableSho
onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
onoff.SetAttribute ("PacketSize", UintegerValue (payloadSize));
onoff.SetAttribute ("DataRate", DataRateValue (54000000)); //bit/s
AddressValue remoteAddress (InetSocketAddress (ApInterface.GetAddress (0), port));
onoff.SetAttribute ("Remote", remoteAddress);
ApplicationContainer apps;
apps.Add (onoff.Install (wifiGStaNodes));
apps.Start (Seconds (1.0));
@@ -207,11 +207,11 @@ Experiment::Run (bool enableProtection, bool enableShortSlotTime, bool enableSho
Simulator::Stop (Seconds (simulationTime + 1));
Simulator::Run ();
Simulator::Destroy ();
totalPacketsThrough = DynamicCast<PacketSink> (sinkApp.Get (0))->GetTotalRx ();
throughput += totalPacketsThrough * 8 / (simulationTime * 1000000.0);
}
return throughput;
}
@@ -220,7 +220,7 @@ int main (int argc, char *argv[])
uint32_t payloadSize = 1472; //bytes
uint32_t simulationTime = 10; //seconds
bool isUdp = true;
CommandLine cmd;
cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize);
cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
@@ -237,67 +237,67 @@ int main (int argc, char *argv[])
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "Disabled" << "\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "G-only" << "\t\t" << throughput <<" Mbit/s" << std::endl;
std::cout << "Disabled" << "\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "G-only" << "\t\t" << throughput << " Mbit/s" << std::endl;
throughput = experiment.Run (false, true, false, false, isUdp, payloadSize, simulationTime);
if (throughput < 29 || throughput > 30)
{
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "Disabled" << "\t\t" << "Short" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "G-only" << "\t\t" << throughput <<" Mbit/s" << std::endl;
std::cout << "Disabled" << "\t\t" << "Short" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "G-only" << "\t\t" << throughput << " Mbit/s" << std::endl;
throughput = experiment.Run (false, false, false, true, isUdp, payloadSize, simulationTime);
if (throughput < 22.5 || throughput > 23.5)
{
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "Disabled" << "\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput <<" Mbit/s" << std::endl;
std::cout << "Disabled" << "\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput << " Mbit/s" << std::endl;
throughput = experiment.Run (false, false, true, true, isUdp, payloadSize, simulationTime);
if (throughput < 22.5 || throughput > 23.5)
{
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "Disabled" << "\t\t" << "Long" << "\t\t\t\t" << "Short" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput <<" Mbit/s" << std::endl;
Config::SetDefault ("ns3::WifiRemoteStationManager::ProtectionMode", StringValue ("Rts-Cts"));
std::cout << "Disabled" << "\t\t" << "Long" << "\t\t\t\t" << "Short" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput << " Mbit/s" << std::endl;
Config::SetDefault ("ns3::WifiRemoteStationManager::ErpProtectionMode", StringValue ("Rts-Cts"));
throughput = experiment.Run (true, false, false, true, isUdp, payloadSize, simulationTime);
if (throughput < 19 || throughput > 20)
{
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "RTS/CTS" << "\t\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput <<" Mbit/s" << std::endl;
std::cout << "RTS/CTS" << "\t\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput << " Mbit/s" << std::endl;
throughput = experiment.Run (true, false, true, true, isUdp, payloadSize, simulationTime);
if (throughput < 19 || throughput > 20)
{
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "RTS/CTS" << "\t\t\t" << "Long" << "\t\t\t\t" << "Short" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput <<" Mbit/s" << std::endl;
Config::SetDefault ("ns3::WifiRemoteStationManager::ProtectionMode", StringValue ("Cts-To-Self"));
std::cout << "RTS/CTS" << "\t\t\t" << "Long" << "\t\t\t\t" << "Short" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput << " Mbit/s" << std::endl;
Config::SetDefault ("ns3::WifiRemoteStationManager::ErpProtectionMode", StringValue ("Cts-To-Self"));
throughput = experiment.Run (true, false, false, true, isUdp, payloadSize, simulationTime);
if (throughput < 20.5 || throughput > 21.5)
{
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "CTS-TO-SELF" << "\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput <<" Mbit/s" << std::endl;
std::cout << "CTS-TO-SELF" << "\t\t" << "Long" << "\t\t\t\t" << "Long" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput << " Mbit/s" << std::endl;
throughput = experiment.Run (true, false, true, true, isUdp, payloadSize, simulationTime);
if (throughput < 20.5 || throughput > 21.5)
{
NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!");
exit (1);
}
std::cout << "CTS-TO-SELF" << "\t\t" << "Long" << "\t\t\t\t" << "Short" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput <<" Mbit/s" << std::endl;
std::cout << "CTS-TO-SELF" << "\t\t" << "Long" << "\t\t\t\t" << "Short" << "\t\t\t\t" << "Mixed" << "\t\t" << throughput << " Mbit/s" << std::endl;
return 0;
}

View File

@@ -325,11 +325,18 @@ WifiRemoteStationManager::GetTypeId (void)
UintegerValue (0),
MakeUintegerAccessor (&WifiRemoteStationManager::m_defaultTxPowerLevel),
MakeUintegerChecker<uint8_t> ())
.AddAttribute ("ProtectionMode",
.AddAttribute ("ErpProtectionMode",
"Protection mode used when non-ERP STAs are connected to an ERP AP: Rts-Cts or Cts-To-Self",
EnumValue (WifiRemoteStationManager::CTS_TO_SELF),
MakeEnumAccessor (&WifiRemoteStationManager::SetProtectionMode,
&WifiRemoteStationManager::GetProtectionMode),
MakeEnumAccessor (&WifiRemoteStationManager::SetErpProtectionMode,
&WifiRemoteStationManager::GetErpProtectionMode),
MakeEnumChecker (WifiRemoteStationManager::RTS_CTS, "Rts-Cts",
WifiRemoteStationManager::CTS_TO_SELF, "Cts-To-Self"))
.AddAttribute ("HtProtectionMode",
"Protection mode used when non-HT STAs are connected to a HT AP: Rts-Cts or Cts-To-Self",
EnumValue (WifiRemoteStationManager::CTS_TO_SELF),
MakeEnumAccessor (&WifiRemoteStationManager::SetHtProtectionMode,
&WifiRemoteStationManager::GetHtProtectionMode),
MakeEnumChecker (WifiRemoteStationManager::RTS_CTS, "Rts-Cts",
WifiRemoteStationManager::CTS_TO_SELF, "Cts-To-Self"))
.AddTraceSource ("MacTxRtsFailed",
@@ -358,6 +365,7 @@ WifiRemoteStationManager::WifiRemoteStationManager ()
m_vhtSupported (false),
m_heSupported (false),
m_useNonErpProtection (false),
m_useNonHtProtection (false),
m_useGreenfieldProtection (false),
m_shortPreambleEnabled (false),
m_shortSlotTimeEnabled (false),
@@ -447,9 +455,15 @@ WifiRemoteStationManager::SetFragmentationThreshold (uint32_t threshold)
}
void
WifiRemoteStationManager::SetProtectionMode (WifiRemoteStationManager::ProtectionMode mode)
WifiRemoteStationManager::SetErpProtectionMode (WifiRemoteStationManager::ProtectionMode mode)
{
m_protectionMode = mode;
m_erpProtectionMode = mode;
}
void
WifiRemoteStationManager::SetHtProtectionMode (WifiRemoteStationManager::ProtectionMode mode)
{
m_htProtectionMode = mode;
}
void
@@ -489,9 +503,15 @@ WifiRemoteStationManager::GetRifsPermitted (void) const
}
WifiRemoteStationManager::ProtectionMode
WifiRemoteStationManager::GetProtectionMode (void) const
WifiRemoteStationManager::GetErpProtectionMode (void) const
{
return m_protectionMode;
return m_erpProtectionMode;
}
WifiRemoteStationManager::ProtectionMode
WifiRemoteStationManager::GetHtProtectionMode (void) const
{
return m_htProtectionMode;
}
bool
@@ -975,7 +995,7 @@ WifiRemoteStationManager::NeedRts (Mac48Address address, const WifiMacHeader *he
{
return false;
}
if (m_protectionMode == RTS_CTS
if (m_erpProtectionMode == RTS_CTS
&& ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
|| (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|| (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
@@ -985,6 +1005,15 @@ WifiRemoteStationManager::NeedRts (Mac48Address address, const WifiMacHeader *he
NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRTS returning true to protect non-ERP stations");
return true;
}
else if (m_htProtectionMode == RTS_CTS
&& ((mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|| (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
&& m_useNonHtProtection
&& !(m_erpProtectionMode != RTS_CTS && m_useNonErpProtection))
{
NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRTS returning true to protect non-HT stations");
return true;
}
bool normally = (packet->GetSize () + header->GetSize () + WIFI_MAC_FCS_LENGTH) > GetRtsCtsThreshold ();
return DoNeedRts (Lookup (address, header), packet, normally);
}
@@ -994,7 +1023,7 @@ WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector)
{
WifiMode mode = txVector.GetMode ();
NS_LOG_FUNCTION (this << mode);
if (m_protectionMode == CTS_TO_SELF
if (m_erpProtectionMode == CTS_TO_SELF
&& ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
|| (mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|| (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
@@ -1004,6 +1033,15 @@ WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector)
NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-ERP stations");
return true;
}
else if (m_htProtectionMode == CTS_TO_SELF
&& ((mode.GetModulationClass () == WIFI_MOD_CLASS_HT)
|| (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
&& m_useNonHtProtection
&& !(m_erpProtectionMode != CTS_TO_SELF && m_useNonErpProtection))
{
NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-HT stations");
return true;
}
else if (!m_useNonErpProtection)
{
//search for the BSS Basic Rate set, if the used mode is in the basic set then there is no need for Cts To Self
@@ -1045,6 +1083,18 @@ WifiRemoteStationManager::GetUseNonErpProtection (void) const
return m_useNonErpProtection;
}
void
WifiRemoteStationManager::SetUseNonHtProtection (bool enable)
{
m_useNonHtProtection = enable;
}
bool
WifiRemoteStationManager::GetUseNonHtProtection (void) const
{
return m_useNonHtProtection;
}
void
WifiRemoteStationManager::SetUseGreenfieldProtection (bool enable)
{

View File

@@ -242,17 +242,29 @@ public:
*/
bool HasHeSupported (void) const;
/**
* Sets the protection mode.
* Sets the ERP protection mode.
*
* \param mode the protection mode
* \param mode the ERP protection mode
*/
void SetProtectionMode (ProtectionMode mode);
void SetErpProtectionMode (ProtectionMode mode);
/**
* Return the protection mode.
* Return the ERP protection mode.
*
* \return the protection mode
* \return the ERP protection mode
*/
ProtectionMode GetProtectionMode (void) const;
ProtectionMode GetErpProtectionMode (void) const;
/**
* Sets the HT protection mode.
*
* \param mode the HT protection mode
*/
void SetHtProtectionMode (ProtectionMode mode);
/**
* Return the HT protection mode.
*
* \return the HT protection mode
*/
ProtectionMode GetHtProtectionMode (void) const;
/**
* Enable or disable protection for non-ERP stations.
*
@@ -266,6 +278,19 @@ public:
* false otherwise
*/
bool GetUseNonErpProtection (void) const;
/**
* Enable or disable protection for non-HT stations.
*
* \param enable enable or disable protection for non-HT stations
*/
void SetUseNonHtProtection (bool enable);
/**
* Return whether the device supports protection of non-HT stations.
*
* \return true if protection for non-HT stations is enabled,
* false otherwise
*/
bool GetUseNonHtProtection (void) const;
/**
* Enable or disable protection for stations that do not support HT greenfield format.
*
@@ -1372,11 +1397,13 @@ private:
uint8_t m_defaultTxPowerLevel; //!< Default tranmission power level
WifiMode m_nonUnicastMode; //!< Transmission mode for non-unicast DATA frames
bool m_useNonErpProtection; //!< flag if protection for non-ERP stations against ERP transmissions is enabled
bool m_useNonHtProtection; //!< flag if protection for non-HT stations against HT transmissions is enabled
bool m_useGreenfieldProtection; //!< flag if protection for stations that do not support HT greenfield format is enabled
bool m_shortPreambleEnabled; //!< flag if short PLCP preamble is enabled
bool m_shortSlotTimeEnabled; //!< flag if short slot time is enabled
bool m_rifsPermitted; //!< flag if RIFS is enabled
ProtectionMode m_protectionMode; //!< Protection mode for ERP stations when non-ERP stations are detected
ProtectionMode m_erpProtectionMode; //!< Protection mode for ERP stations when non-ERP stations are detected
ProtectionMode m_htProtectionMode; //!< Protection mode for HT stations when non-HT stations are detected
/**
* The trace source fired when the transmission of a single RTS has failed