wifi: Make use of RU PHY indices
This commit is contained in:
@@ -732,7 +732,7 @@ HePhy::GetRuBandForTx (const WifiTxVector& txVector, uint16_t staId) const
|
||||
HeRu::RuSpec ru = txVector.GetRu (staId);
|
||||
uint16_t channelWidth = txVector.GetChannelWidth ();
|
||||
NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
|
||||
HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetIndex ());
|
||||
HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetPhyIndex ());
|
||||
HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
|
||||
// for a TX spectrum, the guard bandwidth is a function of the transmission channel width
|
||||
// and the spectrum width equals the transmission channel width (hence bandIndex equals 0)
|
||||
@@ -749,7 +749,7 @@ HePhy::GetRuBandForRx (const WifiTxVector& txVector, uint16_t staId) const
|
||||
HeRu::RuSpec ru = txVector.GetRu (staId);
|
||||
uint16_t channelWidth = txVector.GetChannelWidth ();
|
||||
NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
|
||||
HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetIndex ());
|
||||
HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetPhyIndex ());
|
||||
HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
|
||||
// for an RX spectrum, the guard bandwidth is a function of the operating channel width
|
||||
// and the spectrum width equals the operating channel width
|
||||
@@ -770,8 +770,9 @@ HePhy::GetNonOfdmaBand (const WifiTxVector& txVector, uint16_t staId) const
|
||||
|
||||
// Find the RU that encompasses the non-OFDMA part of the HE TB PPDU for the STA-ID
|
||||
HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (channelWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
|
||||
nonOfdmaRu.SetPhyIndex (channelWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
|
||||
|
||||
HeRu::SubcarrierGroup groupPreamble = HeRu::GetSubcarrierGroup (channelWidth, nonOfdmaRu.GetRuType (), nonOfdmaRu.GetIndex ());
|
||||
HeRu::SubcarrierGroup groupPreamble = HeRu::GetSubcarrierGroup (channelWidth, nonOfdmaRu.GetRuType (), nonOfdmaRu.GetPhyIndex ());
|
||||
HeRu::SubcarrierRange range = std::make_pair (groupPreamble.front ().first, groupPreamble.back ().second);
|
||||
return m_wifiPhy->ConvertHeRuSubcarriers (channelWidth, GetGuardBandwidth (m_wifiPhy->GetChannelWidth ()), range,
|
||||
m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (channelWidth));
|
||||
@@ -879,9 +880,10 @@ HePhy::GetCenterFrequencyForNonOfdmaPart (const WifiTxVector& txVector, uint16_t
|
||||
{
|
||||
//Obtain the index of the non-OFDMA portion
|
||||
HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (currentWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
|
||||
nonOfdmaRu.SetPhyIndex (currentWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
|
||||
|
||||
uint16_t startingFrequency = centerFrequency - (currentWidth / 2);
|
||||
centerFrequency = startingFrequency + nonOfdmaWidth * (nonOfdmaRu.GetIndex () - 1) + nonOfdmaWidth / 2;
|
||||
centerFrequency = startingFrequency + nonOfdmaWidth * (nonOfdmaRu.GetPhyIndex () - 1) + nonOfdmaWidth / 2;
|
||||
}
|
||||
return centerFrequency;
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ HeRu::GetCentral26TonesRus (uint16_t bw, HeRu::RuType ruType)
|
||||
}
|
||||
|
||||
HeRu::SubcarrierGroup
|
||||
HeRu::GetSubcarrierGroup (uint16_t bw, RuType ruType, std::size_t index)
|
||||
HeRu::GetSubcarrierGroup (uint16_t bw, RuType ruType, std::size_t phyIndex)
|
||||
{
|
||||
if (ruType == HeRu::RU_2x996_TONE) //handle special case of RU covering 160 MHz channel
|
||||
{
|
||||
@@ -319,24 +319,24 @@ HeRu::GetSubcarrierGroup (uint16_t bw, RuType ruType, std::size_t index)
|
||||
}
|
||||
|
||||
// Determine the shift to apply to tone indices for 160 MHz channel (i.e. -1012 to 1012), since
|
||||
// m_heRuSubcarrierGroups contains indices for primary 80 MHz subchannel (i.e. from -500 to 500).
|
||||
// The index is used to that aim.
|
||||
std::size_t indexInPrimary80MHz = index;
|
||||
// m_heRuSubcarrierGroups contains indices for lower 80 MHz subchannel (i.e. from -500 to 500).
|
||||
// The phyIndex is used to that aim.
|
||||
std::size_t indexInLower80MHz = phyIndex;
|
||||
std::size_t numRus = GetNRus (bw, ruType);
|
||||
int16_t shift = (bw == 160) ? -512 : 0;
|
||||
if (bw == 160 && index > (numRus / 2))
|
||||
if (bw == 160 && phyIndex > (numRus / 2))
|
||||
{
|
||||
// The provided index is that of the secondary 80 MHz subchannel
|
||||
indexInPrimary80MHz = index - (numRus / 2);
|
||||
// The provided index is that of the upper 80 MHz subchannel
|
||||
indexInLower80MHz = phyIndex - (numRus / 2);
|
||||
shift = 512;
|
||||
}
|
||||
|
||||
auto it = m_heRuSubcarrierGroups.find ({(bw == 160 ? 80 : bw), ruType});
|
||||
|
||||
NS_ABORT_MSG_IF (it == m_heRuSubcarrierGroups.end (), "RU not found");
|
||||
NS_ABORT_MSG_IF (!indexInPrimary80MHz || indexInPrimary80MHz > it->second.size (), "RU index not available");
|
||||
NS_ABORT_MSG_IF (indexInLower80MHz > it->second.size (), "RU index not available");
|
||||
|
||||
SubcarrierGroup group = it->second.at (indexInPrimary80MHz - 1);
|
||||
SubcarrierGroup group = it->second.at (indexInLower80MHz - 1);
|
||||
if (bw == 160)
|
||||
{
|
||||
for (auto & range : group)
|
||||
@@ -357,7 +357,11 @@ HeRu::DoesOverlap (uint16_t bw, RuSpec ru, const std::vector<RuSpec> &v)
|
||||
return true;
|
||||
}
|
||||
|
||||
SubcarrierGroup groups = GetSubcarrierGroup (bw, ru.GetRuType (), ru.GetIndex ());
|
||||
// This function may be called by the MAC layer, hence the PHY index may have
|
||||
// not been set yet. Hence, we pass the "MAC" index to GetSubcarrierGroup instead
|
||||
// of the PHY index. This is fine because we compare the primary 80 MHz bands of
|
||||
// the two RUs below.
|
||||
SubcarrierGroup rangesRu = GetSubcarrierGroup (bw, ru.GetRuType (), ru.GetIndex ());
|
||||
for (auto& p : v)
|
||||
{
|
||||
if (ru.GetPrimary80MHz () != p.GetPrimary80MHz ())
|
||||
@@ -365,9 +369,16 @@ HeRu::DoesOverlap (uint16_t bw, RuSpec ru, const std::vector<RuSpec> &v)
|
||||
// the two RUs are located in distinct 80MHz bands
|
||||
continue;
|
||||
}
|
||||
if (DoesOverlap (bw, p, groups))
|
||||
for (const auto& rangeRu : rangesRu)
|
||||
{
|
||||
return true;
|
||||
SubcarrierGroup rangesP = GetSubcarrierGroup (bw, p.GetRuType (), p.GetIndex ());
|
||||
for (auto& rangeP : rangesP)
|
||||
{
|
||||
if (rangeP.second >= rangeRu.first && rangeRu.second >= rangeP.first)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -383,7 +394,7 @@ HeRu::DoesOverlap (uint16_t bw, RuSpec ru, const SubcarrierGroup &toneRanges)
|
||||
return true;
|
||||
}
|
||||
|
||||
SubcarrierGroup rangesRu = GetSubcarrierGroup (bw, ru.GetRuType (), ru.GetIndex ());
|
||||
SubcarrierGroup rangesRu = GetSubcarrierGroup (bw, ru.GetRuType (), ru.GetPhyIndex ());
|
||||
for (auto& r : rangesRu)
|
||||
{
|
||||
if (range.second >= r.first && r.second >= range.first)
|
||||
@@ -406,7 +417,7 @@ HeRu::FindOverlappingRu (uint16_t bw, RuSpec referenceRu, RuType searchedRuType)
|
||||
{
|
||||
primary80MhzFlags.push_back (true);
|
||||
primary80MhzFlags.push_back (false);
|
||||
numRusPer80Mhz = numRus / 2;
|
||||
numRusPer80Mhz = (searchedRuType == HeRu::RU_2x996_TONE ? 1 : numRus / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -414,9 +425,9 @@ HeRu::FindOverlappingRu (uint16_t bw, RuSpec referenceRu, RuType searchedRuType)
|
||||
numRusPer80Mhz = numRus;
|
||||
}
|
||||
|
||||
std::size_t index = 1;
|
||||
for (const auto primary80MHz : primary80MhzFlags)
|
||||
{
|
||||
std::size_t index = 1;
|
||||
for (std::size_t indexPer80Mhz = 1; indexPer80Mhz <= numRusPer80Mhz; ++indexPer80Mhz, ++index)
|
||||
{
|
||||
RuSpec searchedRu (searchedRuType, index, primary80MHz);
|
||||
|
||||
@@ -161,20 +161,20 @@ public:
|
||||
static std::vector<HeRu::RuSpec> GetCentral26TonesRus (uint16_t bw, HeRu::RuType ruType);
|
||||
|
||||
/**
|
||||
* Get the subcarrier group of the RU having the given index among all the
|
||||
* Get the subcarrier group of the RU having the given PHY index among all the
|
||||
* RUs of the given type (number of tones) available in a HE PPDU of the
|
||||
* given bandwidth. A subcarrier group is defined as one or more pairs
|
||||
* indicating the lowest frequency index and the highest frequency index.
|
||||
* Note that for channel width of 160 MHz the returned range is relative to
|
||||
* the 160 MHz channel (i.e. -1012 to 1012). The index parameter is used to
|
||||
* distinguish between primary and secondary 80 MHz subchannels.
|
||||
* the 160 MHz channel (i.e. -1012 to 1012). The PHY index parameter is used to
|
||||
* distinguish between lower and higher 80 MHz subchannels.
|
||||
*
|
||||
* \param bw the bandwidth (MHz) of the HE PPDU (20, 40, 80, 160)
|
||||
* \param ruType the RU type (number of tones)
|
||||
* \param index the index (starting at 1) of the RU
|
||||
* \param phyIndex the PHY index (starting at 1) of the RU
|
||||
* \return the subcarrier range of the specified RU
|
||||
*/
|
||||
static SubcarrierGroup GetSubcarrierGroup (uint16_t bw, RuType ruType, std::size_t index);
|
||||
static SubcarrierGroup GetSubcarrierGroup (uint16_t bw, RuType ruType, std::size_t phyIndex);
|
||||
|
||||
/**
|
||||
* Check whether the given RU overlaps with the given set of RUs.
|
||||
|
||||
@@ -179,14 +179,24 @@ SpectrumWifiPhy::UpdateInterferenceHelperBands (void)
|
||||
{
|
||||
HeRu::RuType ruType = static_cast <HeRu::RuType> (type);
|
||||
std::size_t nRus = HeRu::GetNRus (bw, ruType);
|
||||
for (std::size_t index = 1; index <= nRus; index++)
|
||||
for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++)
|
||||
{
|
||||
HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (bw, ruType, index);
|
||||
HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (bw, ruType, phyIndex);
|
||||
HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
|
||||
WifiSpectrumBand band = ConvertHeRuSubcarriers (bw, GetGuardBandwidth (channelWidth),
|
||||
range, i);
|
||||
bool primary80 = (channelWidth < 160 || index <= nRus / 2);
|
||||
m_ruBands[channelWidth].insert ({band, HeRu::RuSpec (ruType, index, primary80)});
|
||||
std::size_t index = (bw == 160 && phyIndex > nRus / 2
|
||||
? phyIndex - nRus / 2 : phyIndex);
|
||||
bool primary80IsLower80 = (GetOperatingChannel ().GetPrimaryChannelIndex (20)
|
||||
< bw / 40);
|
||||
bool primary80 = (bw < 160
|
||||
|| ruType == HeRu::RU_2x996_TONE
|
||||
|| (primary80IsLower80 && phyIndex <= nRus / 2)
|
||||
|| (!primary80IsLower80 && phyIndex > nRus / 2));
|
||||
HeRu::RuSpec ru (ruType, index, primary80);
|
||||
ru.SetPhyIndex (bw, GetOperatingChannel ().GetPrimaryChannelIndex (20));
|
||||
NS_ABORT_IF (ru.GetPhyIndex () != phyIndex);
|
||||
m_ruBands[channelWidth].insert ({band, ru});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,6 +480,12 @@ WifiTxVector::GetNumRusPerHeSigBContentChannel (void) const
|
||||
for (auto & userInfo : m_muUserInfos)
|
||||
{
|
||||
HeRu::RuSpec ru = userInfo.second.ru;
|
||||
if (!ru.IsPhyIndexSet ())
|
||||
{
|
||||
// this method can be called when calculating the TX duration of a frame
|
||||
// and at that time the RU PHY index may have not been set yet
|
||||
ru.SetPhyIndex (m_channelWidth, 0);
|
||||
}
|
||||
if (HeRu::DoesOverlap (m_channelWidth, ru, toneRangesContentChannel1))
|
||||
{
|
||||
numRusContentChannel1++;
|
||||
|
||||
@@ -505,7 +505,7 @@ TestDlOfdmaPhyTransmission::SendMuPpdu (uint16_t rxStaId1, uint16_t rxStaId2)
|
||||
txVector.SetMode (HePhy::GetHeMcs7 (), rxStaId1);
|
||||
txVector.SetNss (1, rxStaId1);
|
||||
|
||||
HeRu::RuSpec ru2 (ruType, 2, (m_channelWidth == 160 ? false : true));
|
||||
HeRu::RuSpec ru2 (ruType, (m_channelWidth == 160 ? 1 : 2), (m_channelWidth == 160 ? false : true));
|
||||
txVector.SetRu (ru2, rxStaId2);
|
||||
txVector.SetMode (HePhy::GetHeMcs9 (), rxStaId2);
|
||||
txVector.SetNss (1, rxStaId2);
|
||||
@@ -1440,6 +1440,7 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
|
||||
WifiTxVector txVector = WifiTxVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false);
|
||||
|
||||
HeRu::RuSpec ru (HeRu::RU_106_TONE, staId, false);
|
||||
ru.SetPhyIndex (DEFAULT_CHANNEL_WIDTH, 0);
|
||||
txVector.SetRu (ru, staId);
|
||||
txVector.SetMode (HePhy::GetHeMcs7 (), staId);
|
||||
txVector.SetNss (1, staId);
|
||||
@@ -1903,16 +1904,15 @@ TestUlOfdmaPhyTransmission::GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_
|
||||
NS_ASSERT_MSG (false, "Unsupported channel width");
|
||||
}
|
||||
|
||||
bool primary80MHz;
|
||||
if (m_channelWidth == 160 && (index == 1))
|
||||
{
|
||||
primary80MHz = true;
|
||||
}
|
||||
else
|
||||
bool primary80MHz = true;
|
||||
if (m_channelWidth == 160 && index == 2)
|
||||
{
|
||||
primary80MHz = false;
|
||||
index = 1;
|
||||
}
|
||||
txVector.SetRu (HeRu::RuSpec (ruType, index, primary80MHz), txStaId);
|
||||
HeRu::RuSpec ru (ruType, index, primary80MHz);
|
||||
ru.SetPhyIndex (m_channelWidth, 0);
|
||||
txVector.SetRu (ru, txStaId);
|
||||
txVector.SetMode (HePhy::GetHeMcs7 (), txStaId);
|
||||
txVector.SetNss (1, txStaId);
|
||||
return txVector;
|
||||
|
||||
Reference in New Issue
Block a user