diff -r 9677c1b23cc9 src/wifi/model/ap-wifi-mac.cc --- a/src/wifi/model/ap-wifi-mac.cc Sat Sep 10 14:29:14 2016 -0700 +++ b/src/wifi/model/ap-wifi-mac.cc Mon Sep 12 21:38:00 2016 -0700 @@ -355,7 +355,7 @@ { for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors (); i++) { - rates.SetBasicRate (m_phy->GetBssMembershipSelector (i)); + rates.AddBssMembershipSelectorRate (m_phy->GetBssMembershipSelector (i)); } } // diff -r 9677c1b23cc9 src/wifi/model/sta-wifi-mac.cc --- a/src/wifi/model/sta-wifi-mac.cc Sat Sep 10 14:29:14 2016 -0700 +++ b/src/wifi/model/sta-wifi-mac.cc Mon Sep 12 21:38:00 2016 -0700 @@ -785,7 +785,7 @@ { for (uint32_t i = 0; i < m_phy->GetNBssMembershipSelectors (); i++) { - rates.SetBasicRate (m_phy->GetBssMembershipSelector (i)); + rates.AddBssMembershipSelectorRate (m_phy->GetBssMembershipSelector (i)); } } for (uint32_t i = 0; i < m_phy->GetNModes (); i++) diff -r 9677c1b23cc9 src/wifi/model/supported-rates.cc --- a/src/wifi/model/supported-rates.cc Sat Sep 10 14:29:14 2016 -0700 +++ b/src/wifi/model/supported-rates.cc Mon Sep 12 21:38:00 2016 -0700 @@ -26,14 +26,19 @@ NS_LOG_COMPONENT_DEFINE ("SupportedRates"); +#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 +#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126 + SupportedRates::SupportedRates () : extended (this), m_nRates (0) { + NS_LOG_FUNCTION (this); } SupportedRates::SupportedRates (const SupportedRates &rates) { + NS_LOG_FUNCTION (this); m_nRates = rates.m_nRates; memcpy (m_rates, rates.m_rates, MAX_SUPPORTED_RATES); //reset the back pointer to this object @@ -53,19 +58,40 @@ void SupportedRates::AddSupportedRate (uint32_t bs) { + NS_LOG_FUNCTION (this << bs); + NS_ASSERT_MSG (IsBssMembershipSelectorRate (bs) == false, "Invalid rate"); NS_ASSERT (m_nRates < MAX_SUPPORTED_RATES); - if (IsSupportedRate (bs)) + if (bs == BSS_MEMBERSHIP_SELECTOR_HT_PHY) { - return; + // Encoding defined in Sec. 8.4.2.3, IEEE 802.11-2012 + m_rates[m_nRates] = (BSS_MEMBERSHIP_SELECTOR_HT_PHY | 0x80); + m_nRates++; + NS_LOG_DEBUG ("add HT_PHY membership selector"); } - m_rates[m_nRates] = bs / 500000; - m_nRates++; - NS_LOG_DEBUG ("add rate=" << bs << ", n rates=" << (uint32_t)m_nRates); + else if (bs == BSS_MEMBERSHIP_SELECTOR_VHT_PHY) + { + // Encoding defined in Sec. 8.4.2.3, IEEE 802.11-2012 + m_rates[m_nRates] = (BSS_MEMBERSHIP_SELECTOR_VHT_PHY | 0x80); + m_nRates++; + NS_LOG_DEBUG ("add VHT_PHY membership selector"); + } + else + { + if (IsSupportedRate (bs)) + { + return; + } + m_rates[m_nRates] = bs / 500000; + m_nRates++; + NS_LOG_DEBUG ("add rate=" << bs << ", n rates=" << (uint32_t)m_nRates); + } } void SupportedRates::SetBasicRate (uint32_t bs) { + NS_LOG_FUNCTION (this << bs); + NS_ASSERT_MSG (IsBssMembershipSelectorRate (bs) == false, "Invalid rate"); uint8_t rate = bs / 500000; for (uint8_t i = 0; i < m_nRates; i++) { @@ -84,9 +110,31 @@ SetBasicRate (bs); } +void +SupportedRates::AddBssMembershipSelectorRate (uint32_t bs) +{ + NS_LOG_FUNCTION (this << bs); + if ((bs != BSS_MEMBERSHIP_SELECTOR_HT_PHY) && (bs != BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) + { + NS_ASSERT_MSG (false, "Value " << bs << " not a BSS Membership Selector"); + } + uint32_t rate = (bs | 0x80); + for (uint8_t i = 0; i < m_nRates; i++) + { + if (rate == m_rates[i]) + { + return; + } + } + m_rates[m_nRates] = rate; + NS_LOG_DEBUG ("add BSS membership selector rate " << bs << " as rate " << m_nRates); + m_nRates++; +} + bool SupportedRates::IsBasicRate (uint32_t bs) const { + NS_LOG_FUNCTION (this << bs); uint8_t rate = (bs / 500000) | 0x80; for (uint8_t i = 0; i < m_nRates; i++) { @@ -101,6 +149,7 @@ bool SupportedRates::IsSupportedRate (uint32_t bs) const { + NS_LOG_FUNCTION (this << bs); uint8_t rate = bs / 500000; for (uint8_t i = 0; i < m_nRates; i++) { @@ -113,6 +162,17 @@ return false; } +bool +SupportedRates::IsBssMembershipSelectorRate (uint32_t bs) const +{ + NS_LOG_FUNCTION (this << bs); + if ( (bs & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY || (bs & 0x7f) == BSS_MEMBERSHIP_SELECTOR_VHT_PHY) + { + return true; + } + return false; +} + uint8_t SupportedRates::GetNRates (void) const { diff -r 9677c1b23cc9 src/wifi/model/supported-rates.h --- a/src/wifi/model/supported-rates.h Sat Sep 10 14:29:14 2016 -0700 +++ b/src/wifi/model/supported-rates.h Mon Sep 12 21:38:00 2016 -0700 @@ -129,9 +129,17 @@ * \param bs the rate to be set */ void SetBasicRate (uint32_t bs); - /** - * Check if the given rate is supported. + * Add a special value to the supported rate set, corresponding to + * a BSS membership selector + * + * \param bs the special membership selector value (not a valid rate) + */ + void AddBssMembershipSelectorRate (uint32_t bs); + /** + * Check if the given rate is supported. The rate is encoded as it is + * serialized to the Supported Rates Information Element (i.e. as a + * multiple of 500 Kbits/sec, possibly with MSB set to 1). * * \param bs the rate to be checked * @@ -139,14 +147,25 @@ */ bool IsSupportedRate (uint32_t bs) const; /** - * Check if the given rate is a basic rate. + * Check if the given rate is a basic rate. The rate is encoded as it is + * serialized to the Supported Rates Information Element (i.e. as a + * multiple of 500 Kbits/sec, with MSB set to 1). * * \param bs the rate to be checked * * \return true if the rate is a basic rate, false otherwise */ bool IsBasicRate (uint32_t bs) const; - + /** + * Check if the given rate is a BSS membership selector value. The rate + * is encoded as it is serialized to the Supporting Rates Information + * Element (i.e. with the MSB set to 1). + * + * \param bs the rate to be checked + * + * \return true if the rate is a BSS membership selector, false otherwise + */ + bool IsBssMembershipSelectorRate (uint32_t bs) const; /** * Return the number of supported rates. * @@ -155,6 +174,7 @@ uint8_t GetNRates (void) const; /** * Return the rate at the given index. + * Return the rate (converted back to raw value) at the given index. * * \param i the given index * \return the rate