wifi: add function to reconstruct per user information in TXVECTOR for DL OFDMA
This commit is contained in:
committed by
Sebastien Deronne
parent
27c99b5c5d
commit
0d7bd988e0
@@ -97,9 +97,15 @@ EhtPpdu::SetTxVectorFromPhyHeaders(WifiTxVector& txVector,
|
||||
txVector.SetLength(lSig.GetLength());
|
||||
txVector.SetAggregation(m_psdus.size() > 1 || m_psdus.begin()->second->IsAggregate());
|
||||
txVector.SetEhtPpduType(m_ehtPpduType); // FIXME: PPDU type should be read from U-SIG
|
||||
for (const auto& muUserInfo : m_muUserInfos)
|
||||
if (txVector.IsDlMu())
|
||||
{
|
||||
txVector.SetHeMuUserInfo(muUserInfo.first, muUserInfo.second);
|
||||
auto copyTxVector = txVector;
|
||||
for (const auto& muUserInfo : m_muUserInfos)
|
||||
{
|
||||
txVector.SetHeMuUserInfo(muUserInfo.first, muUserInfo.second);
|
||||
}
|
||||
SetHeMuUserInfos(copyTxVector, heSig);
|
||||
NS_ASSERT(txVector.GetHeMuUserInfoMap() == copyTxVector.GetHeMuUserInfoMap());
|
||||
}
|
||||
if (ns3::IsDlMu(m_preamble))
|
||||
{
|
||||
|
||||
@@ -223,10 +223,13 @@ HePpdu::SetTxVectorFromPhyHeaders(WifiTxVector& txVector,
|
||||
}
|
||||
if (IsDlMu())
|
||||
{
|
||||
auto copyTxVector = txVector;
|
||||
for (const auto& muUserInfo : m_muUserInfos)
|
||||
{
|
||||
txVector.SetHeMuUserInfo(muUserInfo.first, muUserInfo.second);
|
||||
}
|
||||
SetHeMuUserInfos(copyTxVector, heSig);
|
||||
NS_ASSERT(txVector.GetHeMuUserInfoMap() == copyTxVector.GetHeMuUserInfoMap());
|
||||
}
|
||||
if (txVector.IsDlMu())
|
||||
{
|
||||
@@ -241,6 +244,71 @@ HePpdu::SetTxVectorFromPhyHeaders(WifiTxVector& txVector,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HePpdu::SetHeMuUserInfos(WifiTxVector& txVector, const HeSigHeader& heSig) const
|
||||
{
|
||||
WifiTxVector::HeMuUserInfoMap userInfos{};
|
||||
const auto contentChannels = heSig.GetHeSigBContentChannels();
|
||||
const auto ruAllocation = heSig.GetRuAllocation();
|
||||
auto contentChannelIndex = 0;
|
||||
for (const auto& contentChannel : contentChannels)
|
||||
{
|
||||
auto numRusLeft = 0;
|
||||
auto ruAllocIndex = contentChannelIndex;
|
||||
for (const auto& userInfo : contentChannel)
|
||||
{
|
||||
auto ruSpecs = HeRu::GetRuSpecs(ruAllocation.at(ruAllocIndex));
|
||||
if (ruSpecs.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (numRusLeft == 0)
|
||||
{
|
||||
numRusLeft = ruSpecs.size();
|
||||
}
|
||||
auto ruIndex = (ruSpecs.size() - numRusLeft);
|
||||
auto ruSpec = ruSpecs.at(ruIndex);
|
||||
auto ruType = ruSpec.GetRuType();
|
||||
if ((ruAllocation.size() == 8) && (ruType == HeRu::RU_996_TONE) &&
|
||||
(std::all_of(
|
||||
contentChannel.cbegin(),
|
||||
contentChannel.cend(),
|
||||
[&userInfo](const auto& item) { return userInfo.staId == item.staId; })))
|
||||
{
|
||||
NS_ASSERT(txVector.GetChannelWidth() == 160);
|
||||
ruType = HeRu::RU_2x996_TONE;
|
||||
}
|
||||
const auto ruBw = HeRu::GetBandwidth(ruType);
|
||||
auto primary80 = ruAllocIndex < 4;
|
||||
auto num20MhzSubchannelsInRu = (ruBw < 20) ? 1 : (ruBw / 20);
|
||||
auto numRuAllocsInContentChannel = std::max(1, num20MhzSubchannelsInRu / 2);
|
||||
auto ruIndexOffset = (ruBw < 20) ? (ruSpecs.size() * ruAllocIndex)
|
||||
: (ruAllocIndex / num20MhzSubchannelsInRu);
|
||||
if (!primary80)
|
||||
{
|
||||
ruIndexOffset -= HeRu::GetRusOfType(80, ruType).size();
|
||||
}
|
||||
if (!txVector.IsAllocated(userInfo.staId))
|
||||
{
|
||||
txVector.SetHeMuUserInfo(userInfo.staId,
|
||||
{{ruType, ruSpec.GetIndex() + ruIndexOffset, primary80},
|
||||
userInfo.mcs,
|
||||
userInfo.nss});
|
||||
}
|
||||
if (ruType == HeRu::RU_2x996_TONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
numRusLeft--;
|
||||
if (numRusLeft == 0)
|
||||
{
|
||||
ruAllocIndex += (2 * numRuAllocsInContentChannel);
|
||||
}
|
||||
}
|
||||
contentChannelIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
Time
|
||||
HePpdu::GetTxDuration() const
|
||||
{
|
||||
|
||||
@@ -370,6 +370,14 @@ class HePpdu : public OfdmPpdu
|
||||
const LSigHeader& lSig,
|
||||
const HeSigHeader& heSig) const;
|
||||
|
||||
/**
|
||||
* Reconstruct HeMuUserInfoMap from HE-SIG-B header.
|
||||
*
|
||||
* \param txVector the TXVECTOR to set its HeMuUserInfoMap
|
||||
* \param heSig the HE-SIG-B to use to reconstruct HeMuUserInfoMap
|
||||
*/
|
||||
void SetHeMuUserInfos(WifiTxVector& txVector, const HeSigHeader& heSig) const;
|
||||
|
||||
#ifndef NS3_BUILD_PROFILE_DEBUG
|
||||
HeSigHeader m_heSig; //!< the HE-SIG PHY header
|
||||
#endif
|
||||
|
||||
@@ -482,6 +482,12 @@ WifiTxVector::IsUlMu() const
|
||||
return ns3::IsUlMu(m_preamble);
|
||||
}
|
||||
|
||||
bool
|
||||
WifiTxVector::IsAllocated(uint16_t staId) const
|
||||
{
|
||||
return m_muUserInfos.count(staId) > 0;
|
||||
}
|
||||
|
||||
HeRu::RuSpec
|
||||
WifiTxVector::GetRu(uint16_t staId) const
|
||||
{
|
||||
|
||||
@@ -378,6 +378,12 @@ class WifiTxVector
|
||||
* transmission
|
||||
*/
|
||||
bool IsUlMu() const;
|
||||
/**
|
||||
* Check if STA ID is allocated
|
||||
* \param staId STA ID
|
||||
* \return true if allocated, false otherwise
|
||||
*/
|
||||
bool IsAllocated(uint16_t staId) const;
|
||||
/**
|
||||
* Get the RU specification for the STA-ID.
|
||||
* This is applicable only for MU.
|
||||
|
||||
Reference in New Issue
Block a user