wifi: Move remaining function related to HE-SIG-B content channels to HePpdu
This commit is contained in:
committed by
Sébastien Deronne
parent
1ec45cf37e
commit
51b6f880df
@@ -136,7 +136,7 @@ HePpdu::SetHeSigHeader(const WifiTxVector& txVector)
|
||||
.m_giLtfSize = GetGuardIntervalAndNltfEncoding(txVector.GetGuardInterval(),
|
||||
2 /*NLTF currently unused*/),
|
||||
.m_ruAllocation = txVector.GetRuAllocation(p20Index),
|
||||
.m_contentChannels = txVector.GetContentChannels(p20Index),
|
||||
.m_contentChannels = GetContentChannels(txVector, p20Index),
|
||||
.m_center26ToneRuIndication =
|
||||
(txVector.GetChannelWidth() >= 80)
|
||||
? std::optional{txVector.GetCenter26ToneRuIndication()}
|
||||
@@ -493,6 +493,69 @@ HePpdu::GetNumRusPerHeSigBContentChannel(uint16_t channelWidth, const RuAllocati
|
||||
return chSize;
|
||||
}
|
||||
|
||||
HePpdu::HeSigBContentChannels
|
||||
HePpdu::GetContentChannels(const WifiTxVector& txVector, uint8_t p20Index)
|
||||
{
|
||||
HeSigBContentChannels contentChannels{{}};
|
||||
|
||||
const auto channelWidth = txVector.GetChannelWidth();
|
||||
if (channelWidth > 20)
|
||||
{
|
||||
contentChannels.emplace_back();
|
||||
}
|
||||
|
||||
const auto& orderedRus = txVector.GetOrderedRus(p20Index);
|
||||
for (const auto& [ru, staId] : orderedRus)
|
||||
{
|
||||
auto ruType = ru.GetRuType();
|
||||
auto ruIdx = ru.GetIndex();
|
||||
const auto& userInfo = txVector.GetHeMuUserInfo(staId);
|
||||
NS_ASSERT(ru == userInfo.ru);
|
||||
|
||||
if (ruType > HeRu::RU_242_TONE)
|
||||
{
|
||||
for (auto i = 0; i < ((ruType == HeRu::RU_2x996_TONE) ? 2 : 1); ++i)
|
||||
{
|
||||
contentChannels[0].push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
contentChannels[1].push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
std::size_t numRus = (ruType >= HeRu::RU_242_TONE)
|
||||
? 1
|
||||
: HeRu::m_heRuSubcarrierGroups.at({20, ruType}).size();
|
||||
if (((ruIdx - 1) / numRus) % 2 == 0)
|
||||
{
|
||||
contentChannels.at(0).push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
}
|
||||
else
|
||||
{
|
||||
contentChannels.at(1).push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
}
|
||||
}
|
||||
|
||||
// Add unassigned RUs
|
||||
auto numNumRusPerHeSigBContentChannel =
|
||||
GetNumRusPerHeSigBContentChannel(channelWidth, txVector.GetRuAllocation(p20Index));
|
||||
std::size_t contentChannelIndex = 1;
|
||||
for (auto& contentChannel : contentChannels)
|
||||
{
|
||||
const auto totalUsersInContentChannel = (contentChannelIndex == 1)
|
||||
? numNumRusPerHeSigBContentChannel.first
|
||||
: numNumRusPerHeSigBContentChannel.second;
|
||||
NS_ASSERT(contentChannel.size() <= totalUsersInContentChannel);
|
||||
std::size_t unallocatedRus = totalUsersInContentChannel - contentChannel.size();
|
||||
for (std::size_t i = 0; i < unallocatedRus; i++)
|
||||
{
|
||||
contentChannel.push_back({NO_USER_STA_ID, 0, 0});
|
||||
}
|
||||
contentChannelIndex++;
|
||||
}
|
||||
|
||||
return contentChannels;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HePpdu::GetSigBFieldSize(uint16_t channelWidth, const RuAllocation& ruAllocation)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,17 @@ class WifiPsdu;
|
||||
class HePpdu : public OfdmPpdu
|
||||
{
|
||||
public:
|
||||
/// User Specific Fields in HE-SIG-Bs.
|
||||
struct HeSigBUserSpecificField
|
||||
{
|
||||
uint16_t staId : 11; ///< STA-ID
|
||||
uint8_t nss : 4; ///< number of spatial streams
|
||||
uint8_t mcs : 4; ///< MCS index
|
||||
};
|
||||
|
||||
/// HE SIG-B Content Channels
|
||||
using HeSigBContentChannels = std::vector<std::vector<HeSigBUserSpecificField>>;
|
||||
|
||||
/**
|
||||
* HE-SIG PHY header for HE SU PPDUs (HE-SIG-A1/A2)
|
||||
*/
|
||||
@@ -189,6 +200,16 @@ class HePpdu : public OfdmPpdu
|
||||
uint16_t channelWidth,
|
||||
const RuAllocation& ruAllocation);
|
||||
|
||||
/**
|
||||
* Get the HE SIG-B content channels for a given PPDU
|
||||
* IEEE 802.11ax-2021 27.3.11.8.2 HE-SIG-B content channels
|
||||
*
|
||||
* \param txVector the TXVECTOR used for the PPDU
|
||||
* \param p20Index the index of the primary20 channel
|
||||
* \return HE-SIG-B content channels
|
||||
*/
|
||||
static HeSigBContentChannels GetContentChannels(const WifiTxVector& txVector, uint8_t p20Index);
|
||||
|
||||
/**
|
||||
* Get variable length HE SIG-B field size
|
||||
* \param channelWidth the channel width occupied by the PPDU (in MHz)
|
||||
|
||||
@@ -660,68 +660,6 @@ WifiTxVector::GetOrderedRus(uint8_t p20Index) const
|
||||
return orderedRus;
|
||||
}
|
||||
|
||||
HeSigBContentChannels
|
||||
WifiTxVector::GetContentChannels(uint8_t p20Index) const
|
||||
{
|
||||
HeSigBContentChannels contentChannels{{}};
|
||||
|
||||
if (m_channelWidth > 20)
|
||||
{
|
||||
contentChannels.emplace_back();
|
||||
}
|
||||
|
||||
const auto& orderedRus = GetOrderedRus(p20Index);
|
||||
for (const auto& [ru, staId] : orderedRus)
|
||||
{
|
||||
auto ruType = ru.GetRuType();
|
||||
auto ruIdx = ru.GetIndex();
|
||||
const auto& userInfo = GetHeMuUserInfo(staId);
|
||||
NS_ASSERT(ru == userInfo.ru);
|
||||
|
||||
if (ruType > HeRu::RU_242_TONE)
|
||||
{
|
||||
for (auto i = 0; i < ((ruType == HeRu::RU_2x996_TONE) ? 2 : 1); ++i)
|
||||
{
|
||||
contentChannels[0].push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
contentChannels[1].push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
std::size_t numRus = (ruType >= HeRu::RU_242_TONE)
|
||||
? 1
|
||||
: HeRu::m_heRuSubcarrierGroups.at({20, ruType}).size();
|
||||
if (((ruIdx - 1) / numRus) % 2 == 0)
|
||||
{
|
||||
contentChannels.at(0).push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
}
|
||||
else
|
||||
{
|
||||
contentChannels.at(1).push_back({staId, userInfo.nss, userInfo.mcs});
|
||||
}
|
||||
}
|
||||
|
||||
// Add unassigned RUs
|
||||
auto numNumRusPerHeSigBContentChannel =
|
||||
HePpdu::GetNumRusPerHeSigBContentChannel(m_channelWidth, GetRuAllocation(p20Index));
|
||||
std::size_t contentChannelIndex = 1;
|
||||
for (auto& contentChannel : contentChannels)
|
||||
{
|
||||
const auto totalUsersInContentChannel = (contentChannelIndex == 1)
|
||||
? numNumRusPerHeSigBContentChannel.first
|
||||
: numNumRusPerHeSigBContentChannel.second;
|
||||
NS_ASSERT(contentChannel.size() <= totalUsersInContentChannel);
|
||||
std::size_t unallocatedRus = totalUsersInContentChannel - contentChannel.size();
|
||||
for (std::size_t i = 0; i < unallocatedRus; i++)
|
||||
{
|
||||
contentChannel.push_back({NO_USER_STA_ID, 0, 0});
|
||||
}
|
||||
contentChannelIndex++;
|
||||
}
|
||||
|
||||
return contentChannels;
|
||||
}
|
||||
|
||||
RuAllocation
|
||||
WifiTxVector::DeriveRuAllocation(uint8_t p20Index) const
|
||||
{
|
||||
|
||||
@@ -59,17 +59,6 @@ struct HeMuUserInfo
|
||||
bool operator!=(const HeMuUserInfo& other) const;
|
||||
};
|
||||
|
||||
/// User Specific Fields in HE-SIG-Bs.
|
||||
struct HeSigBUserSpecificField
|
||||
{
|
||||
uint16_t staId : 11; ///< STA-ID
|
||||
uint8_t nss : 4; ///< number of spatial streams
|
||||
uint8_t mcs : 4; ///< MCS index
|
||||
};
|
||||
|
||||
/// HE SIG-B Content Channels
|
||||
using HeSigBContentChannels = std::vector<std::vector<HeSigBUserSpecificField>>;
|
||||
|
||||
/// 8 bit RU_ALLOCATION per 20 MHz
|
||||
using RuAllocation = std::vector<uint8_t>;
|
||||
|
||||
@@ -488,14 +477,6 @@ class WifiTxVector
|
||||
*/
|
||||
const RuAllocation& GetRuAllocation(uint8_t p20Index) const;
|
||||
|
||||
/**
|
||||
* Get the HE SIG-B content channels
|
||||
* IEEE 802.11ax-2021 27.3.11.8.2 HE-SIG-B content channels
|
||||
* \param p20Index the index of the primary20 channel
|
||||
* \return HE-SIG-B content channels
|
||||
*/
|
||||
HeSigBContentChannels GetContentChannels(uint8_t p20Index) const;
|
||||
|
||||
/**
|
||||
* Set CENTER_26_TONE_RU field
|
||||
* \param center26ToneRuIndication the CENTER_26_TONE_RU field
|
||||
|
||||
@@ -1396,7 +1396,7 @@ HeSigBDurationTest::DoRun()
|
||||
const auto& numUsersPerCc =
|
||||
HePpdu::GetNumRusPerHeSigBContentChannel(txVector.GetChannelWidth(),
|
||||
txVector.GetRuAllocation(0));
|
||||
const auto contentChannels = txVector.GetContentChannels(0);
|
||||
const auto contentChannels = HePpdu::GetContentChannels(txVector, 0);
|
||||
NS_TEST_EXPECT_MSG_EQ(numUsersPerCc.first,
|
||||
m_expectedNumUsersPerCc.first,
|
||||
"Incorrect number of users in HE-SIG-B content channel 1");
|
||||
|
||||
Reference in New Issue
Block a user