diff --git a/src/wifi/model/he/he-ru.cc b/src/wifi/model/he/he-ru.cc index 4d96244e7..985b59098 100644 --- a/src/wifi/model/he/he-ru.cc +++ b/src/wifi/model/he/he-ru.cc @@ -20,6 +20,7 @@ #include "he-ru.h" #include "ns3/abort.h" +#include "ns3/assert.h" namespace ns3 { @@ -168,6 +169,80 @@ HeRu::GetNRus (uint16_t bw, RuType ruType) return (bw == 160 ? 2 : 1) * it->second.size (); } +std::vector +HeRu::GetRusOfType (uint16_t bw, HeRu::RuType ruType) +{ + if (ruType == HeRu::RU_2x996_TONE) + { + NS_ASSERT (bw >= 160); + return {{true, ruType, 1}}; + } + + std::vector ret; + std::vector primary80MHzSet {true}; + + if (bw == 160) + { + primary80MHzSet.push_back (false); + bw = 80; + } + + for (auto primary80MHz : primary80MHzSet) + { + for (std::size_t ruIndex = 1; ruIndex <= HeRu::m_heRuSubcarrierGroups.at ({bw, ruType}).size (); ruIndex++) + { + ret.push_back ({primary80MHz, ruType, ruIndex}); + } + } + return ret; +} + +std::vector +HeRu::GetCentral26TonesRus (uint16_t bw, HeRu::RuType ruType) +{ + std::vector indices; + + if (ruType == HeRu::RU_52_TONE || ruType == HeRu::RU_106_TONE) + { + if (bw == 20) + { + indices.push_back (5); + } + else if (bw == 40) + { + indices.insert (indices.end (), {5, 14}); + } + else if (bw >= 80) + { + indices.insert (indices.end (), {5, 14, 19, 24, 33}); + } + } + else if (ruType == HeRu::RU_242_TONE || ruType == HeRu::RU_484_TONE) + { + if (bw >= 80) + { + indices.push_back (19); + } + } + + std::vector ret; + std::vector primary80MHzSet {true}; + + if (bw == 160) + { + primary80MHzSet.push_back (false); + } + + for (auto primary80MHz : primary80MHzSet) + { + for (const auto& index : indices) + { + ret.push_back ({primary80MHz, HeRu::RU_26_TONE, index}); + } + } + return ret; +} + HeRu::SubcarrierGroup HeRu::GetSubcarrierGroup (uint16_t bw, RuType ruType, std::size_t index) { @@ -379,4 +454,70 @@ HeRu::GetRuType (uint16_t bandwidth) } } +HeRu::RuType +HeRu::GetEqualSizedRusForStations (uint16_t bandwidth, std::size_t& nStations, + std::size_t& nCentral26TonesRus) +{ + RuType ruType; + uint8_t nRusAssigned = 0; + + // iterate over all the available RU types + for (auto& ru : m_heRuSubcarrierGroups) + { + if (ru.first.first == bandwidth && ru.second.size () <= nStations) + { + ruType = ru.first.second; + nRusAssigned = ru.second.size (); + break; + } + else if (bandwidth == 160 && ru.first.first == 80 && (2 * ru.second.size () <= nStations)) + { + ruType = ru.first.second; + nRusAssigned = 2 * ru.second.size (); + break; + } + } + if (nRusAssigned == 0) + { + NS_ABORT_IF (bandwidth != 160 || nStations != 1); + nRusAssigned = 1; + ruType = RU_2x996_TONE; + } + + nStations = nRusAssigned; + + switch (ruType) + { + case RU_52_TONE: + case RU_106_TONE: + if (bandwidth == 20) + { + nCentral26TonesRus = 1; + } + else if (bandwidth == 40) + { + nCentral26TonesRus = 2; + } + else + { + nCentral26TonesRus = 5; + } + break; + case RU_242_TONE: + case RU_484_TONE: + nCentral26TonesRus = (bandwidth >= 80 ? 1 : 0); + break; + default: + nCentral26TonesRus = 0; + } + + if (bandwidth == 160) + { + nCentral26TonesRus *= 2; + } + + return ruType; +} + + } //namespace ns3 diff --git a/src/wifi/model/he/he-ru.h b/src/wifi/model/he/he-ru.h index ec9f980dd..50c95dd6f 100644 --- a/src/wifi/model/he/he-ru.h +++ b/src/wifi/model/he/he-ru.h @@ -79,6 +79,26 @@ public: */ static std::size_t GetNRus (uint16_t bw, RuType ruType); + /** + * Get the set of distinct RUs of the given type (number of tones) + * available in a HE PPDU of the given bandwidth. + * + * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) + * \param ruType the RU type (number of tones) + * \return the set of distinct RUs available + */ + static std::vector GetRusOfType (uint16_t bw, HeRu::RuType ruType); + + /** + * Get the set of 26-tone RUs that can be additionally allocated if the given + * bandwidth is split in RUs of the given type. + * + * \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160) + * \param ruType the RU type (number of tones) + * \return the set of 26-tone RUs that can be additionally allocated + */ + static std::vector GetCentral26TonesRus (uint16_t bw, HeRu::RuType ruType); + /** * Get the subcarrier group of the RU having the given index among all the * RUs of the given type (number of tones) available in a HE PPDU of the @@ -147,6 +167,22 @@ public: */ static RuType GetRuType (uint16_t bandwidth); + /** + * Given the channel bandwidth and the number of stations candidate for being + * assigned an RU, maximize the number of candidate stations that can be assigned + * an RU subject to the constraint that all the stations must be assigned an RU + * of the same size (in terms of number of tones). + * + * \param bandwidth the channel bandwidth in MHz + * \param nStations the number of candidate stations. On return, it is set to + * the number of stations that are assigned an RU + * \param[out] nCentral26TonesRus the number of additional 26-tone RUs that can be + * allocated if the returned RU size is greater than 26 tones + * \return the RU type + */ + static RuType GetEqualSizedRusForStations (uint16_t bandwidth, std::size_t& nStations, + std::size_t& nCentral26TonesRus); + /// (bandwidth, number of tones) pair typedef std::pair BwTonesPair;