From f7a898ed10ea2a8914368d2d5065a8634f33314e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Thu, 2 Feb 2017 19:04:00 +0100 Subject: [PATCH] wifi: Extend protection mechanisms to support 802.11n --- examples/wireless/mixed-bg-network.cc | 74 +++++++++---------- src/wifi/model/wifi-remote-station-manager.cc | 68 ++++++++++++++--- src/wifi/model/wifi-remote-station-manager.h | 41 ++++++++-- 3 files changed, 130 insertions(+), 53 deletions(-) diff --git a/examples/wireless/mixed-bg-network.cc b/examples/wireless/mixed-bg-network.cc index 90e421e77..1954be136 100644 --- a/examples/wireless/mixed-bg-network.cc +++ b/examples/wireless/mixed-bg-network.cc @@ -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 positionAlloc = CreateObject (); - + 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 (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 (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; } diff --git a/src/wifi/model/wifi-remote-station-manager.cc b/src/wifi/model/wifi-remote-station-manager.cc index 2564441ca..b60ff9a99 100644 --- a/src/wifi/model/wifi-remote-station-manager.cc +++ b/src/wifi/model/wifi-remote-station-manager.cc @@ -325,11 +325,18 @@ WifiRemoteStationManager::GetTypeId (void) UintegerValue (0), MakeUintegerAccessor (&WifiRemoteStationManager::m_defaultTxPowerLevel), MakeUintegerChecker ()) - .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) { diff --git a/src/wifi/model/wifi-remote-station-manager.h b/src/wifi/model/wifi-remote-station-manager.h index 50a267328..ed4fcab43 100644 --- a/src/wifi/model/wifi-remote-station-manager.h +++ b/src/wifi/model/wifi-remote-station-manager.h @@ -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