22 #include "ns3/abort.h"
23 #include "ns3/assert.h"
160 m_primary80MHz (primary80MHz),
184 return m_primary80MHz;
190 bool primary80IsLower80 = (p20Index < bw / 40);
194 || (primary80IsLower80 && m_primary80MHz)
195 || (!primary80IsLower80 && !m_primary80MHz))
197 m_phyIndex = m_index;
201 m_phyIndex = m_index +
GetNRus (bw, m_ruType) / 2;
208 return (m_phyIndex != 0);
235 return (bw == 160 ? 2 : 1) * it->second.size ();
238 std::vector<HeRu::RuSpec>
244 return {{ruType, 1,
true}};
247 std::vector<HeRu::RuSpec> ret;
248 std::vector<bool> primary80MHzSet {
true};
252 primary80MHzSet.push_back (
false);
256 for (
auto primary80MHz : primary80MHzSet)
260 ret.push_back ({ruType, ruIndex, primary80MHz});
266 std::vector<HeRu::RuSpec>
269 std::vector<std::size_t> indices;
275 indices.push_back (5);
279 indices.insert (indices.end (), {5, 14});
283 indices.insert (indices.end (), {5, 14, 19, 24, 33});
290 indices.push_back (19);
294 std::vector<HeRu::RuSpec> ret;
295 std::vector<bool> primary80MHzSet {
true};
299 primary80MHzSet.push_back (
false);
302 for (
auto primary80MHz : primary80MHzSet)
304 for (
const auto& index : indices)
317 NS_ABORT_MSG_IF (bw != 160,
"2x996 tone RU can only be used on 160 MHz band");
318 return {{-1012, -3}, {3, 1012}};
324 std::size_t indexInLower80MHz = phyIndex;
325 std::size_t numRus =
GetNRus (bw, ruType);
326 int16_t shift = (bw == 160) ? -512 : 0;
327 if (bw == 160 && phyIndex > (numRus / 2))
330 indexInLower80MHz = phyIndex - (numRus / 2);
337 NS_ABORT_MSG_IF (indexInLower80MHz > it->second.size (),
"RU index not available");
342 for (
auto & range : group)
344 range.first += shift;
345 range.second += shift;
372 for (
const auto& rangeRu : rangesRu)
375 for (
auto& rangeP : rangesP)
377 if (rangeP.second >= rangeRu.first && rangeRu.second >= rangeP.first)
390 for (
const auto & range : toneRanges)
398 for (
auto& r : rangesRu)
400 if (range.second >= r.first && r.second >= range.first)
414 std::size_t numRusPer80Mhz;
415 std::vector<bool> primary80MhzFlags;
418 primary80MhzFlags.push_back (
true);
419 primary80MhzFlags.push_back (
false);
425 numRusPer80Mhz = numRus;
428 for (
const auto primary80MHz : primary80MhzFlags)
430 std::size_t index = 1;
431 for (std::size_t indexPer80Mhz = 1; indexPer80Mhz <= numRusPer80Mhz; ++indexPer80Mhz, ++index)
433 RuSpec searchedRu (searchedRuType, index, primary80MHz);
440 NS_ABORT_MSG (
"The searched RU type " << searchedRuType <<
" was not found for bw=" << bw <<
" and referenceRu=" << referenceRu);
538 std::size_t& nCentral26TonesRus)
541 uint8_t nRusAssigned = 0;
546 if (ru.first.first == bandwidth && ru.second.size () <= nStations)
548 ruType = ru.first.second;
549 nRusAssigned = ru.second.size ();
552 else if (bandwidth == 160 && ru.first.first == 80 && (2 * ru.second.size () <= nStations))
554 ruType = ru.first.second;
555 nRusAssigned = 2 * ru.second.size ();
559 if (nRusAssigned == 0)
566 nStations = nRusAssigned;
574 nCentral26TonesRus = 1;
576 else if (bandwidth == 40)
578 nCentral26TonesRus = 2;
582 nCentral26TonesRus = 5;
587 nCentral26TonesRus = (bandwidth >= 80 ? 1 : 0);
590 nCentral26TonesRus = 0;
593 if (bandwidth == 160)
595 nCentral26TonesRus *= 2;
RuType GetRuType(void) const
Get the RU type.
RuSpec()
Default constructor.
bool GetPrimary80MHz(void) const
Get the primary 80 MHz flag.
bool IsPhyIndexSet(void) const
Return true if the RU PHY index has been set, false otherwise.
std::size_t GetIndex(void) const
Get the RU index.
void SetPhyIndex(uint16_t bw, uint8_t p20Index)
Set the RU PHY index.
std::size_t GetPhyIndex(void) const
Get the RU PHY index.
static RuSpec FindOverlappingRu(uint16_t bw, RuSpec referenceRu, RuType searchedRuType)
Find the RU allocation of the given RU type overlapping the given reference RU allocation.
static bool DoesOverlap(uint16_t bw, RuSpec ru, const std::vector< RuSpec > &v)
Check whether the given RU overlaps with the given set of RUs.
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
static SubcarrierGroup GetSubcarrierGroup(uint16_t bw, RuType ruType, std::size_t phyIndex)
Get the subcarrier group of the RU having the given PHY index among all the RUs of the given type (nu...
static std::size_t GetNRus(uint16_t bw, RuType ruType)
Get the number of distinct RUs of the given type (number of tones) available in a HE PPDU of the give...
static std::vector< HeRu::RuSpec > GetRusOfType(uint16_t bw, HeRu::RuType ruType)
Get the set of distinct RUs of the given type (number of tones) available in a HE PPDU of the given b...
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
static std::vector< HeRu::RuSpec > GetCentral26TonesRus(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 ...
static const SubcarrierGroups m_heRuSubcarrierGroups
Subcarrier groups for all RUs (with indices being applicable to primary 80 MHz channel)
RuType
The different HE Resource Unit (RU) types.
static RuType GetEqualSizedRusForStations(uint16_t bandwidth, std::size_t &nStations, std::size_t &nCentral26TonesRus)
Given the channel bandwidth and the number of stations candidate for being assigned an RU,...
static RuType GetRuType(uint16_t bandwidth)
Get the RU corresponding to the approximate bandwidth.
std::map< BwTonesPair, std::vector< SubcarrierGroup > > SubcarrierGroups
map (bandwidth, number of tones) pairs to the group of subcarrier ranges
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)