From 0d925018c518bbb6a56b06dd5f112d0cd8941e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Tue, 23 Feb 2016 00:30:01 +0100 Subject: [PATCH] wifi: (fixes #2297) 802.11n/ac backward compatible with legacy --- RELEASE_NOTES | 1 + src/wifi/model/aarf-wifi-manager.cc | 2 +- src/wifi/model/aarfcd-wifi-manager.cc | 2 +- src/wifi/model/amrr-wifi-manager.cc | 2 +- src/wifi/model/ap-wifi-mac.cc | 99 +++- src/wifi/model/ap-wifi-mac.h | 19 +- src/wifi/model/aparf-wifi-manager.cc | 2 +- src/wifi/model/arf-wifi-manager.cc | 2 +- src/wifi/model/cara-wifi-manager.cc | 2 +- src/wifi/model/ht-capabilities.cc | 25 + src/wifi/model/ht-capabilities.h | 4 + src/wifi/model/ht-operations.cc | 519 ++++++++++++++++++ src/wifi/model/ht-operations.h | 245 +++++++++ src/wifi/model/ideal-wifi-manager.cc | 2 +- src/wifi/model/mac-low.cc | 2 +- src/wifi/model/mgt-headers.cc | 44 +- src/wifi/model/mgt-headers.h | 27 + src/wifi/model/minstrel-wifi-manager.cc | 2 +- src/wifi/model/onoe-wifi-manager.cc | 2 +- src/wifi/model/parf-wifi-manager.cc | 2 +- src/wifi/model/rraa-wifi-manager.cc | 2 +- src/wifi/model/sta-wifi-mac.cc | 10 +- src/wifi/model/wifi-information-element.h | 4 +- src/wifi/model/wifi-remote-station-manager.cc | 24 +- src/wifi/model/wifi-remote-station-manager.h | 8 +- src/wifi/model/yans-wifi-phy.cc | 37 +- src/wifi/wscript | 2 + 27 files changed, 1001 insertions(+), 91 deletions(-) create mode 100644 src/wifi/model/ht-operations.cc create mode 100644 src/wifi/model/ht-operations.h diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 0a2ed44d9..0f1fad154 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -106,6 +106,7 @@ Bugs fixed - Bug 2288 - Ipv4 broadcast and multicast packets are replicated on all the interfaces. - Bug 2292 - Uninitialized variables since commit 7c60a9f8f271 - Bug 2293 - Red Queue Estimator spins when trying to compute queue average size under long idle times. +- Bug 2297 - 802.11n/ac networks are not compatible with legacy clients - Bug 2302 - Fixing RTT calculation inside TCP Socket - Bug 2303 - WifiMacQueue::GetSize should cleanup queue beforehand diff --git a/src/wifi/model/aarf-wifi-manager.cc b/src/wifi/model/aarf-wifi-manager.cc index fc5d01639..30c085499 100644 --- a/src/wifi/model/aarf-wifi-manager.cc +++ b/src/wifi/model/aarf-wifi-manager.cc @@ -255,7 +255,7 @@ AarfWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/aarfcd-wifi-manager.cc b/src/wifi/model/aarfcd-wifi-manager.cc index 6301dadcc..db5d3380f 100644 --- a/src/wifi/model/aarfcd-wifi-manager.cc +++ b/src/wifi/model/aarfcd-wifi-manager.cc @@ -327,7 +327,7 @@ AarfcdWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/amrr-wifi-manager.cc b/src/wifi/model/amrr-wifi-manager.cc index bd1d34040..7b433cb02 100644 --- a/src/wifi/model/amrr-wifi-manager.cc +++ b/src/wifi/model/amrr-wifi-manager.cc @@ -357,7 +357,7 @@ AmrrWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) } UpdateMode (station); WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index f6fc9ef1e..fcdad04e6 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -50,21 +50,25 @@ ApWifiMac::GetTypeId (void) .SetParent () .SetGroupName ("Wifi") .AddConstructor () - .AddAttribute ("BeaconInterval", "Delay between two beacons", + .AddAttribute ("BeaconInterval", + "Delay between two beacons", TimeValue (MicroSeconds (102400)), MakeTimeAccessor (&ApWifiMac::GetBeaconInterval, &ApWifiMac::SetBeaconInterval), MakeTimeChecker ()) - .AddAttribute ("BeaconJitter", "A uniform random variable to cause the initial beacon starting time (after simulation time 0) " + .AddAttribute ("BeaconJitter", + "A uniform random variable to cause the initial beacon starting time (after simulation time 0) " "to be distributed between 0 and the BeaconInterval.", StringValue ("ns3::UniformRandomVariable"), MakePointerAccessor (&ApWifiMac::m_beaconJitter), MakePointerChecker ()) - .AddAttribute ("EnableBeaconJitter", "If beacons are enabled, whether to jitter the initial send event.", + .AddAttribute ("EnableBeaconJitter", + "If beacons are enabled, whether to jitter the initial send event.", BooleanValue (false), MakeBooleanAccessor (&ApWifiMac::m_enableBeaconJitter), MakeBooleanChecker ()) - .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.", + .AddAttribute ("BeaconGeneration", + "Whether or not beacons are generated.", BooleanValue (true), MakeBooleanAccessor (&ApWifiMac::SetBeaconGeneration, &ApWifiMac::GetBeaconGeneration), @@ -100,6 +104,7 @@ ApWifiMac::~ApWifiMac () NS_LOG_FUNCTION (this); m_staList.clear(); m_nonErpStations.clear (); + m_nonHtStations.clear (); } void @@ -396,7 +401,7 @@ ApWifiMac::GetErpInformation (void) const if (m_erpSupported) { information.SetNonErpPresent (!m_nonErpStations.empty ()); - information.SetUseProtection (GetUseProtection ()); + information.SetUseProtection (GetUseNonErpProtection ()); if (GetShortPreambleEnabled ()) { information.SetBarkerPreambleMode (0); @@ -442,6 +447,25 @@ ApWifiMac::GetHtCapabilities (void) const return capabilities; } +HtOperations +ApWifiMac::GetHtOperations (void) const +{ + HtOperations operations; + operations.SetHtSupported (1); + if (m_htSupported) + { + if (!m_nonHtStations.empty ()) + { + operations.SetHtProtection (MIXED_MODE_PROTECTION); + } + else + { + operations.SetHtProtection (NO_PROTECTION); + } + } + return operations; +} + VhtCapabilities ApWifiMac::GetVhtCapabilities (void) const { @@ -504,6 +528,7 @@ ApWifiMac::SendProbeResp (Mac48Address to) if (m_htSupported || m_vhtSupported) { probe.SetHtCapabilities (GetHtCapabilities ()); + probe.SetHtOperations (GetHtOperations ()); hdr.SetNoOrder (); } if (m_vhtSupported) @@ -552,6 +577,7 @@ ApWifiMac::SendAssocResp (Mac48Address to, bool success) if (m_htSupported || m_vhtSupported) { assoc.SetHtCapabilities (GetHtCapabilities ()); + assoc.SetHtOperations (GetHtOperations ()); hdr.SetNoOrder (); } if (m_vhtSupported) @@ -593,6 +619,7 @@ ApWifiMac::SendOneBeacon (void) if (m_htSupported || m_vhtSupported) { beacon.SetHtCapabilities (GetHtCapabilities ()); + beacon.SetHtOperations (GetHtOperations ()); hdr.SetNoOrder (); } if (m_vhtSupported) @@ -749,6 +776,9 @@ ApWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsShortPreamble ()); SupportedRates rates = assocReq.GetSupportedRates (); bool problem = false; + bool isVhtStation = false; + bool isHtStation = false; + bool isOfdmStation = false; bool isErpStation = false; bool isDsssStation = false; for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++) @@ -764,7 +794,11 @@ ApWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) { isErpStation = false; } - if (isDsssStation == false && isErpStation == false) + else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM) + { + isOfdmStation = false; + } + if (isDsssStation == false && isErpStation == false && isOfdmStation == false) { problem = true; break; @@ -780,34 +814,46 @@ ApWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) { isErpStation = true; } + else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM) + { + isOfdmStation = true; + } } } m_stationManager->AddSupportedErpSlotTime (from, capabilities.IsShortSlotTime () && isErpStation); if (m_htSupported) { - //check that the STA supports all MCSs in Basic MCS Set + //check whether the HT STA supports all MCSs in Basic MCS Set HtCapabilities htcapabilities = assocReq.GetHtCapabilities (); - for (uint32_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) + if (htcapabilities.GetHtCapabilitiesInfo () != 0) { - WifiMode mcs = m_stationManager->GetBasicMcs (i); - if (!htcapabilities.IsSupportedMcs (mcs.GetMcsValue ())) + isHtStation = true; + for (uint32_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) { - problem = true; - break; + 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 + //check whether the VHT STA supports all MCSs in Basic MCS Set VhtCapabilities vhtcapabilities = assocReq.GetVhtCapabilities (); - for (uint32_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) + if (vhtcapabilities.GetVhtCapabilitiesInfo () != 0) { - WifiMode mcs = m_stationManager->GetBasicMcs (i); - if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) + isVhtStation = true; + for (uint32_t i = 0; i < m_stationManager->GetNBasicMcs (); i++) { - problem = true; - break; + WifiMode mcs = m_stationManager->GetBasicMcs (i); + if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) + { + problem = true; + break; + } } } } @@ -858,6 +904,10 @@ ApWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) } } m_stationManager->RecordWaitAssocTxOk (from); + if (!isHtStation) + { + m_nonHtStations.push_back (hdr->GetAddr2 ()); + } if (!isErpStation && isDsssStation) { m_nonErpStations.push_back (hdr->GetAddr2 ()); @@ -886,6 +936,14 @@ ApWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) break; } } + for (std::list::iterator j = m_nonHtStations.begin (); j != m_nonHtStations.end (); j++) + { + if ((*j) == from) + { + m_nonHtStations.erase (j); + break; + } + } return; } } @@ -947,12 +1005,11 @@ ApWifiMac::DoInitialize (void) } bool -ApWifiMac::GetUseProtection (void) const +ApWifiMac::GetUseNonErpProtection (void) const { bool useProtection = !m_nonErpStations.empty () && m_enableNonErpProtection; - m_stationManager->SetUseProtection (useProtection); + m_stationManager->SetUseNonErpProtection (useProtection); return useProtection; } - } //namespace ns3 diff --git a/src/wifi/model/ap-wifi-mac.h b/src/wifi/model/ap-wifi-mac.h index f5e9f052d..07c5a2de1 100644 --- a/src/wifi/model/ap-wifi-mac.h +++ b/src/wifi/model/ap-wifi-mac.h @@ -26,6 +26,7 @@ #include "regular-wifi-mac.h" #include "capability-information.h" #include "ht-capabilities.h" +#include "ht-operations.h" #include "vht-capabilities.h" #include "amsdu-subframe-header.h" #include "supported-rates.h" @@ -213,6 +214,12 @@ private: * \return the HT capability that we support */ HtCapabilities GetHtCapabilities (void) const; + /** + * Return the HT operations of the current AP. + * + * \return the HT operations that we support + */ + HtOperations GetHtOperations (void) const; /** * Return the VHT capability of the current AP. * @@ -238,8 +245,13 @@ private: * \return true if beacons are periodically generated, false otherwise */ bool GetBeaconGeneration (void) const; - - bool GetUseProtection (void) const; + /** + * Return whether protection for non-ERP stations is used in the BSS. + * + * \return true if protection for non-ERP stations is used in the BSS, + * false otherwise + */ + bool GetUseNonErpProtection (void) const; virtual void DoDispose (void); virtual void DoInitialize (void); @@ -251,7 +263,8 @@ private: Ptr m_beaconJitter; //!< UniformRandomVariable used to randomize the time of the first beacon bool m_enableBeaconJitter; //!< Flag whether the first beacon should be generated at random time std::list m_staList; //!< List of all stations currently associated to the AP - std::list m_nonErpStations; //!< List of all 802.11b stations currently associated to the AP + std::list m_nonErpStations; //!< List of all non-ERP stations currently associated to the AP + std::list m_nonHtStations; //!< List of all non-HT stations currently associated to the AP bool m_enableNonErpProtection; //!< Flag whether protection mechanism is used or not when non-ERP STAs are present within the BSS }; diff --git a/src/wifi/model/aparf-wifi-manager.cc b/src/wifi/model/aparf-wifi-manager.cc index 71039b208..3b01ee903 100644 --- a/src/wifi/model/aparf-wifi-manager.cc +++ b/src/wifi/model/aparf-wifi-manager.cc @@ -346,7 +346,7 @@ AparfWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/arf-wifi-manager.cc b/src/wifi/model/arf-wifi-manager.cc index deb12961f..f5a71b912 100644 --- a/src/wifi/model/arf-wifi-manager.cc +++ b/src/wifi/model/arf-wifi-manager.cc @@ -231,7 +231,7 @@ ArfWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/cara-wifi-manager.cc b/src/wifi/model/cara-wifi-manager.cc index f96b12fa8..7a88b5c1f 100644 --- a/src/wifi/model/cara-wifi-manager.cc +++ b/src/wifi/model/cara-wifi-manager.cc @@ -206,7 +206,7 @@ CaraWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/ht-capabilities.cc b/src/wifi/model/ht-capabilities.cc index 37601e3c2..2e74ce4af 100644 --- a/src/wifi/model/ht-capabilities.cc +++ b/src/wifi/model/ht-capabilities.cc @@ -174,12 +174,24 @@ HtCapabilities::SetTxMcsSetDefined (uint8_t txmcssetdefined) m_txMcsSetDefined = txmcssetdefined; } +void +HtCapabilities::SetTxRxMcsSetUnequal (uint8_t txrxmcssetunequal) +{ + m_txRxMcsSetUnequal = txrxmcssetunequal; +} + void HtCapabilities::SetTxMaxNSpatialStreams (uint8_t maxtxspatialstreams) { m_txMaxNSpatialStreams = maxtxspatialstreams; } +void +HtCapabilities::SetTxUnequalModulation (uint8_t txunequalmodulation) +{ + m_txUnequalModulation = txunequalmodulation; +} + uint8_t HtCapabilities::GetLdpc (void) const { @@ -258,12 +270,25 @@ HtCapabilities::GetTxMcsSetDefined (void) const return m_txMcsSetDefined; } +uint8_t +HtCapabilities::GetTxRxMcsSetUnequal (void) const +{ + return m_txRxMcsSetUnequal; +} + + uint8_t HtCapabilities::GetTxMaxNSpatialStreams (void) const { return m_txMaxNSpatialStreams; } +uint8_t +HtCapabilities::GetTxUnequalModulation (void) const +{ + return m_txUnequalModulation; +} + uint8_t HtCapabilities::GetInformationFieldSize () const { diff --git a/src/wifi/model/ht-capabilities.h b/src/wifi/model/ht-capabilities.h index 3315a2521..262c787bd 100644 --- a/src/wifi/model/ht-capabilities.h +++ b/src/wifi/model/ht-capabilities.h @@ -100,7 +100,9 @@ public: void SetRxMcsBitmask (uint8_t index); void SetRxHighestSupportedDataRate (uint16_t maxsupportedrate); void SetTxMcsSetDefined (uint8_t txmcssetdefined); + void SetTxRxMcsSetUnequal (uint8_t txrxmcssetunequal); void SetTxMaxNSpatialStreams (uint8_t maxtxspatialstreams); + void SetTxUnequalModulation (uint8_t txunequalmodulation); /* * Return the HT Capabilties Info field in the HT Capabilities information element. @@ -159,7 +161,9 @@ public: bool IsSupportedMcs (uint8_t mcs); uint16_t GetRxHighestSupportedDataRate (void) const; uint8_t GetTxMcsSetDefined (void) const; + uint8_t GetTxRxMcsSetUnequal (void) const; uint8_t GetTxMaxNSpatialStreams (void) const; + uint8_t GetTxUnequalModulation (void) const; WifiInformationElementId ElementId () const; uint8_t GetInformationFieldSize () const; diff --git a/src/wifi/model/ht-operations.cc b/src/wifi/model/ht-operations.cc new file mode 100644 index 000000000..68c1be5f3 --- /dev/null +++ b/src/wifi/model/ht-operations.cc @@ -0,0 +1,519 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2016 Sébastien 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 + */ + +#include "ht-operations.h" +#include "ns3/assert.h" +#include "ns3/log.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("HtOperations"); + +HtOperations::HtOperations () + : m_primaryChannel (0), + m_secondaryChannelOffset (0), + m_staChannelWidth (0), + m_rifsMode (0), + m_reservedInformationSubset1 (0), + m_htProtection (0), + m_nonGfHtStasPresent (0), + m_reservedInformationSubset2_1 (0), + m_obssNonHtStasPresent (0), + m_reservedInformationSubset2_2 (0), + m_reservedInformationSubset3_1 (0), + m_dualBeacon (0), + m_dualCtsProtection (0), + m_stbcBeacon (0), + m_lSigTxopProtectionFullSupport (0), + m_pcoActive (0), + m_pcoPhase (0), + m_reservedInformationSubset3_2 (0), + m_reservedMcsSet1 (0), + m_rxHighestSupportedDataRate (0), + m_reservedMcsSet2 (0), + m_txMcsSetDefined (0), + m_txRxMcsSetUnequal (0), + m_txMaxNSpatialStreams (0), + m_txUnequalModulation (0), + m_reservedMcsSet3 (0), + m_htSupported (0) +{ + for (uint32_t k = 0; k < MAX_SUPPORTED_MCS; k++) + { + m_rxMcsBitmask[k] = 0; + } +} + +WifiInformationElementId +HtOperations::ElementId () const +{ + return IE_HT_OPERATIONS; +} + +void +HtOperations::SetHtSupported (uint8_t htsupported) +{ + m_htSupported = htsupported; +} + +uint8_t +HtOperations::GetInformationFieldSize () const +{ + //we should not be here if ht is not supported + NS_ASSERT (m_htSupported > 0); + return 22; +} + +void +HtOperations::SetPrimaryChannel (uint8_t ctrl) +{ + m_primaryChannel = ctrl; +} + +void +HtOperations::SetSecondaryChannelOffset (uint8_t secondarychanneloffset) +{ + m_secondaryChannelOffset = secondarychanneloffset; +} + +void +HtOperations::SetStaChannelWidth (uint8_t stachannelwidth) +{ + m_staChannelWidth = stachannelwidth; +} + +void +HtOperations::SetRifsMode (uint8_t rifsmode) +{ + m_rifsMode = rifsmode; +} + +void +HtOperations::SetHtProtection (uint8_t htprotection) +{ + m_htProtection = htprotection; +} + +void +HtOperations::SetNonGfHtStasPresent (uint8_t nongfhtstaspresent) +{ + m_nonGfHtStasPresent = nongfhtstaspresent; +} + +void +HtOperations::SetObssNonHtStasPresent (uint8_t obssnonhtstaspresent) +{ + m_obssNonHtStasPresent = obssnonhtstaspresent; +} + +void +HtOperations::SetDualBeacon (uint8_t dualbeacon) +{ + m_dualBeacon = dualbeacon; +} + +void +HtOperations::SetDualCtsProtection (uint8_t dualctsprotection) +{ + m_dualCtsProtection = dualctsprotection; +} + +void +HtOperations::SetStbcBeacon (uint8_t stbcbeacon) +{ + m_stbcBeacon = stbcbeacon; +} + +void +HtOperations::SetLSigTxopProtectionFullSupport (uint8_t lsigtxopprotectionfullsupport) +{ + m_lSigTxopProtectionFullSupport = lsigtxopprotectionfullsupport; +} + +void +HtOperations::SetPcoActive (uint8_t pcoactive) +{ + m_pcoActive = pcoactive; +} + +void +HtOperations::SetPhase (uint8_t pcophase) +{ + m_pcoPhase = pcophase; +} + +void +HtOperations::SetRxMcsBitmask (uint8_t index) +{ + m_rxMcsBitmask[index] = 1; +} + +void +HtOperations::SetRxHighestSupportedDataRate (uint16_t maxsupportedrate) +{ + m_rxHighestSupportedDataRate = maxsupportedrate; +} + +void +HtOperations::SetTxMcsSetDefined (uint8_t txmcssetdefined) +{ + m_txMcsSetDefined = txmcssetdefined; +} + +void +HtOperations::SetTxRxMcsSetUnequal (uint8_t txrxmcssetunequal) +{ + m_txRxMcsSetUnequal = txrxmcssetunequal; +} + +void +HtOperations::SetTxMaxNSpatialStreams (uint8_t maxtxspatialstreams) +{ + m_txMaxNSpatialStreams = maxtxspatialstreams; +} + +void +HtOperations::SetTxUnequalModulation (uint8_t txunequalmodulation) +{ + m_txUnequalModulation = txunequalmodulation; +} + +uint8_t +HtOperations::GetPrimaryChannel (void) const +{ + return m_primaryChannel; +} + +uint8_t +HtOperations::GetSecondaryChannelOffset (void) const +{ + return m_secondaryChannelOffset; +} + +uint8_t +HtOperations::GetStaChannelWidth (void) const +{ + return m_staChannelWidth; +} + +uint8_t +HtOperations::GetRifsMode (void) const +{ + return m_rifsMode; +} + +uint8_t +HtOperations::GetHtProtection (void) const +{ + return m_htProtection; +} + +uint8_t +HtOperations::GetNonGfHtStasPresent (void) const +{ + return m_nonGfHtStasPresent; +} + +uint8_t +HtOperations::GetObssNonHtStasPresent (void) const +{ + return m_obssNonHtStasPresent; +} + +uint8_t +HtOperations::GetDualBeacon (void) const +{ + return m_dualBeacon; +} + +uint8_t +HtOperations::GetDualCtsProtection (void) const +{ + return m_dualCtsProtection; +} + +uint8_t +HtOperations::GetStbcBeacon (void) const +{ + return m_stbcBeacon; +} + +uint8_t +HtOperations::GetLSigTxopProtectionFullSupport (void) const +{ + return m_lSigTxopProtectionFullSupport; +} + +uint8_t +HtOperations::GetPcoActive (void) const +{ + return m_pcoActive; +} + +uint8_t +HtOperations::GetPhase (void) const +{ + return m_pcoPhase; +} + +bool +HtOperations::IsSupportedMcs (uint8_t mcs) +{ + if (m_rxMcsBitmask[mcs] == 1) + { + return true; + } + return false; +} + +uint16_t +HtOperations::GetRxHighestSupportedDataRate (void) const +{ + return m_rxHighestSupportedDataRate; +} + +uint8_t +HtOperations::GetTxMcsSetDefined (void) const +{ + return m_txMcsSetDefined; +} + +uint8_t +HtOperations::GetTxRxMcsSetUnequal (void) const +{ + return m_txRxMcsSetUnequal; +} + +uint8_t +HtOperations::GetTxMaxNSpatialStreams (void) const +{ + return m_txMaxNSpatialStreams; +} + +uint8_t +HtOperations::GetTxUnequalModulation (void) const +{ + return m_txUnequalModulation; +} + +Buffer::Iterator +HtOperations::Serialize (Buffer::Iterator i) const +{ + if (m_htSupported < 1) + { + return i; + } + return WifiInformationElement::Serialize (i); +} + +uint16_t +HtOperations::GetSerializedSize () const +{ + if (m_htSupported < 1) + { + return 0; + } + return WifiInformationElement::GetSerializedSize (); +} + +uint8_t +HtOperations::GetInformationSubset1 (void) const +{ + uint16_t val = 0; + val |= m_secondaryChannelOffset & 0x03; + val |= (m_staChannelWidth & 0x01) << 2; + val |= (m_rifsMode & 0x01) << 3; + val |= (m_reservedInformationSubset1 & 0x0f) << 4; + return val; +} + +void +HtOperations::SetInformationSubset1 (uint8_t ctrl) +{ + m_secondaryChannelOffset = ctrl & 0x03; + m_staChannelWidth = (ctrl >> 2) & 0x01; + m_rifsMode = (ctrl >> 3) & 0x01; + m_reservedInformationSubset1 = (ctrl >> 4) & 0x0f; +} + +uint16_t +HtOperations::GetInformationSubset2 (void) const +{ + uint16_t val = 0; + val |= m_htProtection & 0x03; + val |= (m_nonGfHtStasPresent & 0x01) << 2; + val |= (m_reservedInformationSubset2_1 & 0x01) << 3; + val |= (m_obssNonHtStasPresent & 0x01) << 4; + val |= (m_reservedInformationSubset2_1 & 0x07ff) << 5; + return val; +} + +void +HtOperations::SetInformationSubset2 (uint16_t ctrl) +{ + m_htProtection = ctrl & 0x03; + m_nonGfHtStasPresent = (ctrl >> 2) & 0x01; + m_reservedInformationSubset2_1 = (ctrl >> 3) & 0x01; + m_obssNonHtStasPresent = (ctrl >> 4) & 0x01; + m_reservedInformationSubset2_1 = (ctrl >> 5) & 0x07ff; +} + +uint16_t +HtOperations::GetInformationSubset3 (void) const +{ + uint16_t val = 0; + val |= m_reservedInformationSubset3_1 & 0x3f; + val |= (m_dualBeacon & 0x01) << 6; + val |= (m_dualCtsProtection & 0x01) << 7; + val |= (m_stbcBeacon & 0x01) << 8; + val |= (m_lSigTxopProtectionFullSupport & 0x01) << 9; + val |= (m_pcoActive & 0x01) << 10; + val |= (m_pcoPhase & 0x01) << 11; + val |= (m_reservedInformationSubset3_2 & 0x0f) << 12; + return val; +} + +void +HtOperations::SetInformationSubset3 (uint16_t ctrl) +{ + m_reservedInformationSubset3_1 = ctrl & 0x3f; + m_dualBeacon = (ctrl >> 6) & 0x01; + m_dualCtsProtection = (ctrl >> 7) & 0x01; + m_stbcBeacon = (ctrl >> 8) & 0x01; + m_lSigTxopProtectionFullSupport = (ctrl >> 9) & 0x01; + m_pcoActive = (ctrl >> 10) & 0x01; + m_pcoPhase = (ctrl >> 11) & 0x01; + m_reservedInformationSubset3_2 = (ctrl >> 12) & 0x0f; +} + +void +HtOperations::SetBasicMcsSet (uint64_t ctrl1, uint64_t ctrl2) +{ + for (uint64_t i = 0; i < 77; i++) + { + if (i < 64) + { + m_rxMcsBitmask[i] = (ctrl1 >> i) & 0x01; + } + else + { + m_rxMcsBitmask[i] = (ctrl2 >> (i - 64)) & 0x01; + } + } + m_reservedMcsSet1 = (ctrl2 >> 13) & 0x07; + m_rxHighestSupportedDataRate = (ctrl2 >> 16) & 0x03ff; + m_reservedMcsSet2 = (ctrl2 >> 26) & 0x3f; + m_txMcsSetDefined = (ctrl2 >> 32) & 0x01; + m_txRxMcsSetUnequal = (ctrl2 >> 33) & 0x01; + m_txMaxNSpatialStreams = (ctrl2 >> 34) & 0x03; + m_txUnequalModulation = (ctrl2 >> 36) & 0x01; + m_reservedMcsSet3 = (ctrl2 >> 37) & 0x07ffffff; +} + +uint64_t +HtOperations::GetBasicMcsSet1 (void) const +{ + uint64_t val = 0; + for (uint64_t i = 63; i > 0; i--) + { + val = (val << 1) | (m_rxMcsBitmask[i] & 0x01); + } + val = (val << 1) | (m_rxMcsBitmask[0] & 0x01); + return val; +} + +uint64_t +HtOperations::GetBasicMcsSet2 (void) const +{ + uint64_t val = 0; + val = val | (m_reservedMcsSet3 & 0x07ffffff); + val = (val << 1) | (m_txUnequalModulation & 0x01); + val = (val << 2) | (m_txMaxNSpatialStreams & 0x03); + val = (val << 1) | (m_txRxMcsSetUnequal & 0x01); + val = (val << 1) | (m_txMcsSetDefined & 0x01); + val = (val << 6) | (m_reservedMcsSet2 & 0x3f); + val = (val << 10) | (m_rxHighestSupportedDataRate & 0x3ff); + val = (val << 3) | (m_reservedMcsSet1 & 0x07); + + for (uint64_t i = 13; i > 0; i--) + { + val = (val << 1) | ( m_rxMcsBitmask[i + 63] & 0x01); + } + return val; +} + +void +HtOperations::SerializeInformationField (Buffer::Iterator start) const +{ + if (m_htSupported == 1) + { + //write the corresponding value for each bit + start.WriteU8 (GetPrimaryChannel ()); + start.WriteU8 (GetInformationSubset1 ()); + start.WriteU16 (GetInformationSubset2 ()); + start.WriteU16 (GetInformationSubset3 ()); + start.WriteHtolsbU64 (GetBasicMcsSet1 ()); + start.WriteHtolsbU64 (GetBasicMcsSet2 ()); + } +} + +uint8_t +HtOperations::DeserializeInformationField (Buffer::Iterator start, + uint8_t length) +{ + Buffer::Iterator i = start; + uint8_t primarychannel = i.ReadU8 (); + uint8_t informationsubset1 = i.ReadU8 (); + uint8_t informationsubset2 = i.ReadU16 (); + uint8_t informationsubset3 = i.ReadU16 (); + uint64_t mcsset1 = i.ReadLsbtohU64 (); + uint64_t mcsset2 = i.ReadLsbtohU64 (); + SetPrimaryChannel (primarychannel); + SetInformationSubset1 (informationsubset1); + SetInformationSubset2 (informationsubset2); + SetInformationSubset3 (informationsubset3); + SetBasicMcsSet (mcsset1, mcsset2); + return length; +} + +ATTRIBUTE_HELPER_CPP (HtOperations); + +std::ostream & +operator << (std::ostream &os, const HtOperations &htoperations) +{ + os << bool (htoperations.GetStaChannelWidth ()) + << "|" << bool (htoperations.GetRifsMode ()) + << "|" << bool (htoperations.GetDualCtsProtection()); + + return os; +} + +std::istream &operator >> (std::istream &is, HtOperations &htoperations) +{ + bool c1, c2, c3; + is >> c1 >> c2 >> c3; + htoperations.SetStaChannelWidth (c1); + htoperations.SetRifsMode (c2); + htoperations.SetDualCtsProtection (c3); + + return is; +} + +} //namespace ns3 diff --git a/src/wifi/model/ht-operations.h b/src/wifi/model/ht-operations.h new file mode 100644 index 000000000..b4f2cfa13 --- /dev/null +++ b/src/wifi/model/ht-operations.h @@ -0,0 +1,245 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2016 Sébastien 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 + */ + +#ifndef HT_OPERATIONS_H +#define HT_OPERATIONS_H + +#include +#include "ns3/buffer.h" +#include "ns3/attribute-helper.h" +#include "ns3/wifi-information-element.h" + +/** + * This defines the maximum number of supported MCSs that a STA is + * allowed to have. Currently this number is set for IEEE 802.11n + */ +#define MAX_SUPPORTED_MCS (77) + +namespace ns3 { + +enum HtProtectionType +{ + NO_PROTECTION, + NON_MEMBER_PROTECTION, + TWENTY_MHZ_PROTECTION, + MIXED_MODE_PROTECTION +}; + +/** + * \brief The HT Operations Information Element + * \ingroup wifi + * + * This class knows how to serialise and deserialise + * the HT Operations Information Element + * + * \see attribute_HtOperations + */ +class HtOperations: public WifiInformationElement +{ +public: + HtOperations (); + void SetHtSupported (uint8_t htsupported); + + /** + * Set the Primary Channel field in the HT Operations information element. + * + * \param ctrl the Primary Channel field in the HT Operations information element + */ + void SetPrimaryChannel (uint8_t ctrl); + /** + * Set the Information Subset 1 field in the HT Operations information element. + * + * \param ctrl the Information Subset 1 field in the HT Operations information element + */ + void SetInformationSubset1 (uint8_t ctrl); + /** + * Set the Information Subset 2 field in the HT Operations information element. + * + * \param ctrl the Information Subset 2 field in the HT Operations information element + */ + void SetInformationSubset2 (uint16_t ctrl); + /** + * Set the Information Subset 3 field in the HT Operations information element. + * + * \param ctrl the Information Subset 3 field in the HT Operations information element + */ + void SetInformationSubset3 (uint16_t ctrl); + /** + * Set the Basic MCS Set field in the HT Operations information element. + * + * \param ctrl1 the first 64 bytes of the Basic MCS Set field in the HT Operations information element + * \param ctrl2 the last 64 bytes of the Basic MCS Set field in the HT Operations information element + */ + void SetBasicMcsSet (uint64_t ctrl1, uint64_t ctrl2); + + void SetSecondaryChannelOffset (uint8_t secondarychanneloffset); + void SetStaChannelWidth (uint8_t stachannelwidth); + void SetRifsMode (uint8_t rifsmode); + + void SetHtProtection (uint8_t htprotection); + void SetNonGfHtStasPresent (uint8_t nongfhtstaspresent); + void SetObssNonHtStasPresent (uint8_t obssnonhtstaspresent); + + void SetDualBeacon (uint8_t dualbeacon); + void SetDualCtsProtection (uint8_t dualctsprotection); + void SetStbcBeacon (uint8_t stbcbeacon); + void SetLSigTxopProtectionFullSupport (uint8_t lsigtxopprotectionfullsupport); + void SetPcoActive (uint8_t pcoactive); + void SetPhase (uint8_t pcophase); + + void SetRxMcsBitmask (uint8_t index); + void SetRxHighestSupportedDataRate (uint16_t maxsupportedrate); + void SetTxMcsSetDefined (uint8_t txmcssetdefined); + void SetTxRxMcsSetUnequal (uint8_t txrxmcssetunequal); + void SetTxMaxNSpatialStreams (uint8_t maxtxspatialstreams); + void SetTxUnequalModulation (uint8_t txunequalmodulation); + + /* + * Return the Primary Channel field in the HT Operations information element. + * + * \return the Primary Channel field in the HT Operations information element + */ + uint8_t GetPrimaryChannel (void) const; + /* + * Return the Information Subset 1 field in the HT Operations information element. + * + * \return the Information Subset 1 field in the HT Operations information element + */ + uint8_t GetInformationSubset1 (void) const; + /* + * Return the Information Subset 2 field in the HT Operations information element. + * + * \return the Information Subset 2 field in the HT Operations information element + */ + uint16_t GetInformationSubset2 (void) const; + /* + * Return the Information Subset 3 field in the HT Operations information element. + * + * \return the Information Subset 3 field in the HT Operations information element + */ + uint16_t GetInformationSubset3 (void) const; + /* + * Return the first 64 bytes of the Basic MCS Set field in the HT Operations information element. + * + * \return the first 64 bytes of the Basic MCS Set field in the HT Operations information element + */ + uint64_t GetBasicMcsSet1 (void) const; + /* + * Return the last 64 bytes of the Basic MCS Set field in the HT Operations information element. + * + * \return the last 64 bytes of the Basic MCS Set field in the HT Operations information element + */ + uint64_t GetBasicMcsSet2 (void) const; + + uint8_t GetSecondaryChannelOffset (void) const; + uint8_t GetStaChannelWidth (void) const; + uint8_t GetRifsMode (void) const; + + uint8_t GetHtProtection (void) const; + uint8_t GetNonGfHtStasPresent (void) const; + uint8_t GetObssNonHtStasPresent (void) const; + + uint8_t GetDualBeacon (void) const; + uint8_t GetDualCtsProtection (void) const; + uint8_t GetStbcBeacon (void) const; + uint8_t GetLSigTxopProtectionFullSupport (void) const; + uint8_t GetPcoActive (void) const; + uint8_t GetPhase (void) const; + + bool IsSupportedMcs (uint8_t mcs); + uint16_t GetRxHighestSupportedDataRate (void) const; + uint8_t GetTxMcsSetDefined (void) const; + uint8_t GetTxRxMcsSetUnequal (void) const; + uint8_t GetTxMaxNSpatialStreams (void) const; + uint8_t GetTxUnequalModulation (void) const; + + WifiInformationElementId ElementId () const; + uint8_t GetInformationFieldSize () const; + void SerializeInformationField (Buffer::Iterator start) const; + uint8_t DeserializeInformationField (Buffer::Iterator start, + uint8_t length); + /** + * This information element is a bit special in that it is only + * included if the STA is an HT STA. To support this we + * override the Serialize and GetSerializedSize methods of + * WifiInformationElement. + * + * \param start + * + * \return an iterator + */ + Buffer::Iterator Serialize (Buffer::Iterator start) const; + /** + * Return the serialized size of this HT Operations IE. + * + * \return the serialized size of this HT Operations IE + */ + uint16_t GetSerializedSize () const; + + +private: + uint8_t m_primaryChannel; + + //HT Information Subset 1 + uint8_t m_secondaryChannelOffset; + uint8_t m_staChannelWidth; + uint8_t m_rifsMode; + uint8_t m_reservedInformationSubset1; + + //HT Information Subset 2 + uint8_t m_htProtection; + uint8_t m_nonGfHtStasPresent; + uint8_t m_reservedInformationSubset2_1; + uint8_t m_obssNonHtStasPresent; + uint8_t m_reservedInformationSubset2_2; + + //HT Information Subset 3 + uint8_t m_reservedInformationSubset3_1; + uint8_t m_dualBeacon; + uint8_t m_dualCtsProtection; + uint8_t m_stbcBeacon; + uint8_t m_lSigTxopProtectionFullSupport; + uint8_t m_pcoActive; + uint8_t m_pcoPhase; + uint8_t m_reservedInformationSubset3_2; + + //Basic MCS Set field + uint8_t m_reservedMcsSet1; + uint16_t m_rxHighestSupportedDataRate; + uint8_t m_reservedMcsSet2; + uint8_t m_txMcsSetDefined; + uint8_t m_txRxMcsSetUnequal; + uint8_t m_txMaxNSpatialStreams; + uint8_t m_txUnequalModulation; + uint32_t m_reservedMcsSet3; + uint8_t m_rxMcsBitmask[MAX_SUPPORTED_MCS]; + + //This is used to decide whether this element should be added to the frame or not + uint8_t m_htSupported; +}; + +std::ostream &operator << (std::ostream &os, const HtOperations &htoperations); +std::istream &operator >> (std::istream &is, HtOperations &htoperations); + +ATTRIBUTE_HELPER_HEADER (HtOperations); + +} //namespace ns3 + +#endif /* HT_OPERATIONS_H */ diff --git a/src/wifi/model/ideal-wifi-manager.cc b/src/wifi/model/ideal-wifi-manager.cc index b4a0d7d17..bc82228b5 100644 --- a/src/wifi/model/ideal-wifi-manager.cc +++ b/src/wifi/model/ideal-wifi-manager.cc @@ -187,7 +187,7 @@ IdealWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) //ensure correct packet delivery. double maxThreshold = 0.0; WifiMode maxMode = GetDefaultMode (); - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { for (uint32_t i = 0; i < GetNBasicModes (); i++) { diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc index e645d27a2..749a303b8 100644 --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -807,7 +807,7 @@ MacLow::StartTransmission (Ptr packet, } else { - if ((m_ctsToSelfSupported || m_stationManager->GetUseProtection ()) && NeedCtsToSelf ()) + if ((m_ctsToSelfSupported || m_stationManager->GetUseNonErpProtection ()) && NeedCtsToSelf ()) { SendCtsToSelf (); } diff --git a/src/wifi/model/mgt-headers.cc b/src/wifi/model/mgt-headers.cc index 11fe66ed3..21378f0b6 100644 --- a/src/wifi/model/mgt-headers.cc +++ b/src/wifi/model/mgt-headers.cc @@ -209,6 +209,18 @@ MgtProbeResponseHeader::GetHtCapabilities (void) const return m_htCapability; } +void +MgtProbeResponseHeader::SetHtOperations (HtOperations htoperations) +{ + m_htOperations = htoperations; +} + +HtOperations +MgtProbeResponseHeader::GetHtOperations (void) const +{ + return m_htOperations; +} + void MgtProbeResponseHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities) { @@ -281,6 +293,7 @@ MgtProbeResponseHeader::GetSerializedSize (void) const size += m_erpInformation.GetSerializedSize (); size += m_rates.extended.GetSerializedSize (); size += m_htCapability.GetSerializedSize (); + size += m_htOperations.GetSerializedSize (); size += m_vhtCapability.GetSerializedSize (); return size; } @@ -292,6 +305,7 @@ MgtProbeResponseHeader::Print (std::ostream &os) const << "rates=" << m_rates << ", " << "ERP information=" << m_erpInformation << ", " << "HT Capabilities=" << m_htCapability << " , " + << "HT Operations=" << m_htOperations << " , " << "VHT Capabilities= " << m_vhtCapability; } @@ -317,6 +331,7 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const i = m_erpInformation.Serialize (i); i = m_rates.extended.Serialize (i); i = m_htCapability.Serialize (i); + i = m_htOperations.Serialize (i); i = m_vhtCapability.Serialize (i); } @@ -334,6 +349,7 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start) i = m_erpInformation.DeserializeIfPresent (i); i = m_rates.extended.DeserializeIfPresent (i); i = m_htCapability.DeserializeIfPresent (i); + i = m_htOperations.DeserializeIfPresent (i); i = m_vhtCapability.DeserializeIfPresent (i); return i.GetDistanceFrom (start); } @@ -570,6 +586,24 @@ MgtAssocResponseHeader::SetHtCapabilities (HtCapabilities htcapabilities) m_htCapability = htcapabilities; } +HtCapabilities +MgtAssocResponseHeader::GetHtCapabilities (void) const +{ + return m_htCapability; +} + +void +MgtAssocResponseHeader::SetHtOperations (HtOperations htoperations) +{ + m_htOperations = htoperations; +} + +HtOperations +MgtAssocResponseHeader::GetHtOperations (void) const +{ + return m_htOperations; +} + void MgtAssocResponseHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities) { @@ -582,12 +616,6 @@ MgtAssocResponseHeader::GetVhtCapabilities (void) const return m_vhtCapability; } -HtCapabilities -MgtAssocResponseHeader::GetHtCapabilities (void) const -{ - return m_htCapability; -} - void MgtAssocResponseHeader::SetErpInformation (ErpInformation erpInformation) { @@ -629,6 +657,7 @@ MgtAssocResponseHeader::GetSerializedSize (void) const size += m_erpInformation.GetSerializedSize (); size += m_rates.extended.GetSerializedSize (); size += m_htCapability.GetSerializedSize (); + size += m_htOperations.GetSerializedSize (); size += m_vhtCapability.GetSerializedSize (); return size; } @@ -640,6 +669,7 @@ MgtAssocResponseHeader::Print (std::ostream &os) const << "rates=" << m_rates << ", " << "ERP information=" << m_erpInformation << ", " << "HT Capabilities=" << m_htCapability << " , " + << "HT Operations=" << m_htOperations << " , " << "VHT Capabilities= " << m_vhtCapability; } @@ -654,6 +684,7 @@ MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const i = m_erpInformation.Serialize (i); i = m_rates.extended.Serialize (i); i = m_htCapability.Serialize (i); + i = m_htOperations.Serialize (i); i = m_vhtCapability.Serialize (i); } @@ -668,6 +699,7 @@ MgtAssocResponseHeader::Deserialize (Buffer::Iterator start) i = m_erpInformation.DeserializeIfPresent (i); i = m_rates.extended.DeserializeIfPresent (i); i = m_htCapability.DeserializeIfPresent (i); + i = m_htOperations.DeserializeIfPresent (i); i = m_vhtCapability.DeserializeIfPresent (i); return i.GetDistanceFrom (start); } diff --git a/src/wifi/model/mgt-headers.h b/src/wifi/model/mgt-headers.h index ac3a6e5a7..970ff1f9d 100644 --- a/src/wifi/model/mgt-headers.h +++ b/src/wifi/model/mgt-headers.h @@ -31,6 +31,7 @@ #include "supported-rates.h" #include "ssid.h" #include "ht-capabilities.h" +#include "ht-operations.h" #include "vht-capabilities.h" #include "erp-information.h" @@ -181,6 +182,12 @@ public: * \return HT capabilities */ HtCapabilities GetHtCapabilities (void) const; + /** + * Return the HT operations. + * + * \return HT operations + */ + HtOperations GetHtOperations (void) const; /** * Return the ERP information. * @@ -205,6 +212,12 @@ public: * \param htcapabilities HT capabilities */ void SetHtCapabilities (HtCapabilities htcapabilities); + /** + * Set the HT operations. + * + * \param htoperations HT operations + */ + void SetHtOperations (HtOperations htoperations); /** * Set the supported rates. * @@ -242,6 +255,7 @@ private: StatusCode m_code; //!< Status code uint16_t m_aid; HtCapabilities m_htCapability; //!< HT capabilities + HtOperations m_htOperations; //!< HT operations VhtCapabilities m_vhtCapability; //!< VHT capabilities ErpInformation m_erpInformation; //!< ERP information }; @@ -365,6 +379,12 @@ public: * \return HT capabilities */ HtCapabilities GetHtCapabilities (void) const; + /** + * Return the HT operations. + * + * \return HT operations + */ + HtOperations GetHtOperations (void) const; /** * Return the VHT capabilities. * @@ -389,6 +409,12 @@ public: * \param htcapabilities HT capabilities */ void SetHtCapabilities (HtCapabilities htcapabilities); + /** + * Set the HT operations. + * + * \param htoperations HT operations + */ + void SetHtOperations (HtOperations htoperations); /** * Set the VHT capabilities. * @@ -445,6 +471,7 @@ private: SupportedRates m_rates; //!< List of supported rates CapabilityInformation m_capability; //!< Capability information HtCapabilities m_htCapability; //!< HT capabilities + HtOperations m_htOperations; //!< HT operations VhtCapabilities m_vhtCapability; //!< VHT capabilities ErpInformation m_erpInformation; //!< ERP information }; diff --git a/src/wifi/model/minstrel-wifi-manager.cc b/src/wifi/model/minstrel-wifi-manager.cc index f89902b74..8c4e50c6b 100644 --- a/src/wifi/model/minstrel-wifi-manager.cc +++ b/src/wifi/model/minstrel-wifi-manager.cc @@ -503,7 +503,7 @@ MinstrelWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/onoe-wifi-manager.cc b/src/wifi/model/onoe-wifi-manager.cc index 3099ee60a..05f6b3597 100644 --- a/src/wifi/model/onoe-wifi-manager.cc +++ b/src/wifi/model/onoe-wifi-manager.cc @@ -299,7 +299,7 @@ OnoeWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) } UpdateMode (station); WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/parf-wifi-manager.cc b/src/wifi/model/parf-wifi-manager.cc index f87f0b3be..67f6bc094 100644 --- a/src/wifi/model/parf-wifi-manager.cc +++ b/src/wifi/model/parf-wifi-manager.cc @@ -318,7 +318,7 @@ ParfWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/rraa-wifi-manager.cc b/src/wifi/model/rraa-wifi-manager.cc index 770c7ac0c..1361f7073 100644 --- a/src/wifi/model/rraa-wifi-manager.cc +++ b/src/wifi/model/rraa-wifi-manager.cc @@ -310,7 +310,7 @@ RraaWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) channelWidth = 20; } WifiTxVector rtsTxVector; - if (GetUseProtection () == false) + if (GetUseNonErpProtection () == false) { rtsTxVector = WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (st), false, 1, 0, channelWidth, GetAggregation (station), false); } diff --git a/src/wifi/model/sta-wifi-mac.cc b/src/wifi/model/sta-wifi-mac.cc index 85aeba148..055875c07 100644 --- a/src/wifi/model/sta-wifi-mac.cc +++ b/src/wifi/model/sta-wifi-mac.cc @@ -37,6 +37,7 @@ #include "amsdu-subframe-header.h" #include "mgt-headers.h" #include "ht-capabilities.h" +#include "ht-operations.h" #include "vht-capabilities.h" /* @@ -521,11 +522,11 @@ StaWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) isShortPreambleEnabled &= !erpInformation.GetBarkerPreambleMode (); if (erpInformation.GetUseProtection() == true) { - m_stationManager->SetUseProtection (true); + m_stationManager->SetUseNonErpProtection (true); } else { - m_stationManager->SetUseProtection (false); + m_stationManager->SetUseNonErpProtection (false); } if (capabilities.IsShortSlotTime () == true) { @@ -590,11 +591,11 @@ StaWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) ErpInformation erpInformation = probeResp.GetErpInformation (); if (erpInformation.GetUseProtection() == true) { - m_stationManager->SetUseProtection (true); + m_stationManager->SetUseNonErpProtection (true); } else { - m_stationManager->SetUseProtection (false); + m_stationManager->SetUseNonErpProtection (false); } if (capabilities.IsShortSlotTime () == true) { @@ -662,6 +663,7 @@ StaWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) if (m_htSupported) { HtCapabilities htcapabilities = assocResp.GetHtCapabilities (); + HtOperations htOperations = assocResp.GetHtOperations (); m_stationManager->AddStationHtCapabilities (hdr->GetAddr2 (),htcapabilities); } if (m_vhtSupported) diff --git a/src/wifi/model/wifi-information-element.h b/src/wifi/model/wifi-information-element.h index 4d4674bbe..74c121d8c 100644 --- a/src/wifi/model/wifi-information-element.h +++ b/src/wifi/model/wifi-information-element.h @@ -83,7 +83,9 @@ typedef uint8_t WifiInformationElementId; #define IE_RSN ((WifiInformationElementId)48) // 49 is reserved in 802.11-2007 #define IE_EXTENDED_SUPPORTED_RATES ((WifiInformationElementId)50) -// 51 to 126 are reserved in 802.11-2007 +// 51 to 60 are reserved in 802.11-2007 +#define IE_HT_OPERATIONS ((WifiInformationElementId)61) +// 62 to 126 are reserved in 802.11-2007 #define IE_EXTENDED_CAPABILITIES ((WifiInformationElementId)127) // 128 to 190 are reserved in 802.11-2007 #define IE_VHT_CAPABILITIES ((WifiInformationElementId)191) diff --git a/src/wifi/model/wifi-remote-station-manager.cc b/src/wifi/model/wifi-remote-station-manager.cc index 582ba6ffa..82e03757e 100644 --- a/src/wifi/model/wifi-remote-station-manager.cc +++ b/src/wifi/model/wifi-remote-station-manager.cc @@ -360,7 +360,7 @@ WifiRemoteStationManager::GetTypeId (void) WifiRemoteStationManager::WifiRemoteStationManager () : m_htSupported (false), m_vhtSupported (false), - m_useProtection (false), + m_useNonErpProtection (false), m_shortPreambleEnabled (false), m_shortSlotTimeEnabled (false) { @@ -868,8 +868,10 @@ WifiRemoteStationManager::NeedRts (Mac48Address address, const WifiMacHeader *he WifiMode mode = txVector.GetMode (); NS_LOG_FUNCTION (this << address << *header << packet << mode); if (m_protectionMode == RTS_CTS - && mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM - && m_useProtection) + && ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) + || (mode.GetModulationClass () == WIFI_MOD_CLASS_HT) + || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)) + && m_useNonErpProtection) { NS_LOG_DEBUG ("WifiRemoteStationManager::NeedRTS returning true to protect non-ERP stations"); return true; @@ -888,13 +890,15 @@ WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector) WifiMode mode = txVector.GetMode (); NS_LOG_FUNCTION (this << mode); if (m_protectionMode == CTS_TO_SELF - && mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM - && m_useProtection) + && ((mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) + || (mode.GetModulationClass () == WIFI_MOD_CLASS_HT) + || (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT)) + && m_useNonErpProtection) { NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true to protect non-ERP stations"); return true; } - else if (!m_useProtection) + 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 for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++) @@ -924,15 +928,15 @@ WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector) } void -WifiRemoteStationManager::SetUseProtection (bool enable) +WifiRemoteStationManager::SetUseNonErpProtection (bool enable) { - m_useProtection = enable; + m_useNonErpProtection = enable; } bool -WifiRemoteStationManager::GetUseProtection (void) const +WifiRemoteStationManager::GetUseNonErpProtection (void) const { - return m_useProtection; + return m_useNonErpProtection; } bool diff --git a/src/wifi/model/wifi-remote-station-manager.h b/src/wifi/model/wifi-remote-station-manager.h index d1cdb67b5..dfe32eb8d 100644 --- a/src/wifi/model/wifi-remote-station-manager.h +++ b/src/wifi/model/wifi-remote-station-manager.h @@ -95,7 +95,7 @@ public: enum ProtectionMode { - RTS_CTS = 0, + RTS_CTS, CTS_TO_SELF }; @@ -223,14 +223,14 @@ public: * * \param enable enable or disable protection for non-ERP stations */ - void SetUseProtection (bool enable); + void SetUseNonErpProtection (bool enable); /** * Return whether the device supports protection of non-ERP stations. * * \return true if protection for non-ERP stations is enabled, * false otherwise */ - bool GetUseProtection (void) const; + bool GetUseNonErpProtection (void) const; /** * Enable or disable short PLCP preambles. * @@ -1176,7 +1176,7 @@ private: uint32_t m_nextFragmentationThreshold; //!< Threshold for fragmentation that will be used for the next transmission uint8_t m_defaultTxPowerLevel; //!< Default tranmission power level WifiMode m_nonUnicastMode; //!< Transmission mode for non-unicast DATA frames - bool m_useProtection; //!< flag if protection for non-ERP stations against ERP transmissions is enabled + bool m_useNonErpProtection; //!< flag if protection for non-ERP stations against ERP transmissions is enabled bool m_shortPreambleEnabled; //!< flag if short PLCP preamble is enabled bool m_shortSlotTimeEnabled; //!< flag if short slot time is enabled ProtectionMode m_protectionMode; //!< Protection mode for ERP stations when non-ERP stations are detected diff --git a/src/wifi/model/yans-wifi-phy.cc b/src/wifi/model/yans-wifi-phy.cc index 07509c3d6..79b5cf70b 100644 --- a/src/wifi/model/yans-wifi-phy.cc +++ b/src/wifi/model/yans-wifi-phy.cc @@ -904,15 +904,11 @@ void YansWifiPhy::Configure80211g (void) { NS_LOG_FUNCTION (this); - m_channelStartingFrequency = 2407; //2.407 GHz + Configure80211b (); SetChannelWidth (20); //20 MHz - m_deviceRateSet.push_back (WifiPhy::GetDsssRate1Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetDsssRate2Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetDsssRate5_5Mbps ()); m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate6Mbps ()); m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate9Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetDsssRate11Mbps ()); m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate12Mbps ()); m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate18Mbps ()); m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate24Mbps ()); @@ -973,23 +969,16 @@ void 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 ()); - m_deviceRateSet.push_back (WifiPhy::GetDsssRate2Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetDsssRate5_5Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate6Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetDsssRate11Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate12Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetErpOfdmRate24Mbps ()); + Configure80211b (); + Configure80211g (); } if (m_channelStartingFrequency >= 5000 && m_channelStartingFrequency <= 6000) //at 5 GHz { - m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12Mbps ()); - m_deviceRateSet.push_back (WifiPhy::GetOfdmRate24Mbps ()); + Configure80211a (); } + SetChannelWidth (20); //20 MHz m_deviceMcsSet.push_back (WifiPhy::GetHtMcs0 ()); m_deviceMcsSet.push_back (WifiPhy::GetHtMcs1 ()); @@ -1007,22 +996,10 @@ void YansWifiPhy::Configure80211ac (void) { NS_LOG_FUNCTION (this); - m_channelStartingFrequency = 5e3; //5.000 GHz + m_channelStartingFrequency = 5e3; //5.000 GHz + Configure80211n (); 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 ()); diff --git a/src/wifi/wscript b/src/wifi/wscript index 75a201261..102789d35 100644 --- a/src/wifi/wscript +++ b/src/wifi/wscript @@ -73,6 +73,7 @@ def build(bld): 'model/wifi-tx-current-model.cc', 'model/vht-capabilities.cc', 'model/erp-information.cc', + 'model/ht-operations.cc', 'helper/wifi-radio-energy-model-helper.cc', 'helper/vht-wifi-mac-helper.cc', 'helper/ht-wifi-mac-helper.cc', @@ -168,6 +169,7 @@ def build(bld): 'model/wifi-tx-current-model.h', 'model/vht-capabilities.h', 'model/erp-information.h', + 'model/ht-operations.h', 'helper/wifi-radio-energy-model-helper.h', 'helper/vht-wifi-mac-helper.h', 'helper/ht-wifi-mac-helper.h',