wifi: Preliminary support for EHT variant Common/User Info field of Trigger Frames
This commit is contained in:
@@ -1068,8 +1068,10 @@ CtrlBAckResponseHeader::ResetBitmap(std::size_t index)
|
||||
* Trigger frame - User Info field
|
||||
***********************************/
|
||||
|
||||
CtrlTriggerUserInfoField::CtrlTriggerUserInfoField(TriggerFrameType triggerType)
|
||||
: m_aid12(0),
|
||||
CtrlTriggerUserInfoField::CtrlTriggerUserInfoField(TriggerFrameType triggerType,
|
||||
TriggerFrameVariant variant)
|
||||
: m_variant(variant),
|
||||
m_aid12(0),
|
||||
m_ruAllocation(0),
|
||||
m_ulFecCodingType(false),
|
||||
m_ulMcs(0),
|
||||
@@ -1096,11 +1098,13 @@ CtrlTriggerUserInfoField::operator=(const CtrlTriggerUserInfoField& userInfo)
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_variant = userInfo.m_variant;
|
||||
m_aid12 = userInfo.m_aid12;
|
||||
m_ruAllocation = userInfo.m_ruAllocation;
|
||||
m_ulFecCodingType = userInfo.m_ulFecCodingType;
|
||||
m_ulMcs = userInfo.m_ulMcs;
|
||||
m_ulDcm = userInfo.m_ulDcm;
|
||||
m_ps160 = userInfo.m_ps160;
|
||||
m_bits26To31 = userInfo.m_bits26To31;
|
||||
m_ulTargetRssi = userInfo.m_ulTargetRssi;
|
||||
m_basicTriggerDependentUserInfo = userInfo.m_basicTriggerDependentUserInfo;
|
||||
@@ -1111,7 +1115,8 @@ CtrlTriggerUserInfoField::operator=(const CtrlTriggerUserInfoField& userInfo)
|
||||
void
|
||||
CtrlTriggerUserInfoField::Print(std::ostream& os) const
|
||||
{
|
||||
os << ", USER_INFO AID=" << m_aid12 << ", RU_Allocation=" << +m_ruAllocation
|
||||
os << ", USER_INFO " << (m_variant == TriggerFrameVariant::HE ? "HE" : "EHT")
|
||||
<< " variant AID=" << m_aid12 << ", RU_Allocation=" << +m_ruAllocation
|
||||
<< ", MCS=" << +m_ulMcs;
|
||||
}
|
||||
|
||||
@@ -1155,7 +1160,10 @@ CtrlTriggerUserInfoField::Serialize(Buffer::Iterator start) const
|
||||
userInfo |= (m_ruAllocation << 12);
|
||||
userInfo |= (m_ulFecCodingType ? 1 << 20 : 0);
|
||||
userInfo |= (m_ulMcs & 0x0f) << 21;
|
||||
userInfo |= (m_ulDcm ? 1 << 25 : 0);
|
||||
if (m_variant == TriggerFrameVariant::HE)
|
||||
{
|
||||
userInfo |= (m_ulDcm ? 1 << 25 : 0);
|
||||
}
|
||||
|
||||
if (m_aid12 != 0 && m_aid12 != 2045)
|
||||
{
|
||||
@@ -1169,10 +1177,15 @@ CtrlTriggerUserInfoField::Serialize(Buffer::Iterator start) const
|
||||
}
|
||||
|
||||
i.WriteHtolsbU32(userInfo);
|
||||
// Here we need to write 8 bits covering the UL Target RSSI (7 bits) and the
|
||||
// Reserved bit. Given how m_ulTargetRssi is set, writing m_ulTargetRssi
|
||||
// leads to setting the Reserved bit to zero
|
||||
i.WriteU8(m_ulTargetRssi);
|
||||
// Here we need to write 8 bits covering the UL Target RSSI (7 bits) and B39, which is
|
||||
// reserved in the HE variant and the PS160 subfield in the EHT variant.
|
||||
uint8_t bit32To39 = m_ulTargetRssi;
|
||||
if (m_variant == TriggerFrameVariant::EHT)
|
||||
{
|
||||
bit32To39 |= (m_ps160 ? 1 << 7 : 0);
|
||||
}
|
||||
|
||||
i.WriteU8(bit32To39);
|
||||
|
||||
if (m_triggerType == TriggerFrameType::BASIC_TRIGGER)
|
||||
{
|
||||
@@ -1206,7 +1219,10 @@ CtrlTriggerUserInfoField::Deserialize(Buffer::Iterator start)
|
||||
m_ruAllocation = (userInfo >> 12) & 0xff;
|
||||
m_ulFecCodingType = (userInfo >> 20) & 0x01;
|
||||
m_ulMcs = (userInfo >> 21) & 0x0f;
|
||||
m_ulDcm = (userInfo >> 25) & 0x01;
|
||||
if (m_variant == TriggerFrameVariant::HE)
|
||||
{
|
||||
m_ulDcm = (userInfo >> 25) & 0x01;
|
||||
}
|
||||
|
||||
if (m_aid12 != 0 && m_aid12 != 2045)
|
||||
{
|
||||
@@ -1219,7 +1235,12 @@ CtrlTriggerUserInfoField::Deserialize(Buffer::Iterator start)
|
||||
m_bits26To31.raRuInformation.moreRaRu = (userInfo >> 31) & 0x01;
|
||||
}
|
||||
|
||||
m_ulTargetRssi = i.ReadU8() & 0x7f; // B39 is reserved
|
||||
uint8_t bit32To39 = i.ReadU8();
|
||||
m_ulTargetRssi = bit32To39 & 0x7f; // B39 is reserved in HE variant
|
||||
if (m_variant == TriggerFrameVariant::EHT)
|
||||
{
|
||||
m_ps160 = (bit32To39 >> 7) == 1;
|
||||
}
|
||||
|
||||
if (m_triggerType == TriggerFrameType::BASIC_TRIGGER)
|
||||
{
|
||||
@@ -1240,6 +1261,21 @@ CtrlTriggerUserInfoField::GetType() const
|
||||
return m_triggerType;
|
||||
}
|
||||
|
||||
WifiPreamble
|
||||
CtrlTriggerUserInfoField::GetPreambleType() const
|
||||
{
|
||||
switch (m_variant)
|
||||
{
|
||||
case TriggerFrameVariant::HE:
|
||||
return WIFI_PREAMBLE_HE_TB;
|
||||
case TriggerFrameVariant::EHT:
|
||||
return WIFI_PREAMBLE_EHT_TB;
|
||||
default:
|
||||
NS_ABORT_MSG("Unexpected variant: " << +static_cast<uint8_t>(m_variant));
|
||||
}
|
||||
return WIFI_PREAMBLE_LONG; // to silence warning
|
||||
}
|
||||
|
||||
void
|
||||
CtrlTriggerUserInfoField::SetAid12(uint16_t aid)
|
||||
{
|
||||
@@ -1387,12 +1423,14 @@ CtrlTriggerUserInfoField::GetUlMcs() const
|
||||
void
|
||||
CtrlTriggerUserInfoField::SetUlDcm(bool dcm)
|
||||
{
|
||||
NS_ASSERT_MSG(m_variant == TriggerFrameVariant::HE, "UL DCM flag only present in HE variant");
|
||||
m_ulDcm = dcm;
|
||||
}
|
||||
|
||||
bool
|
||||
CtrlTriggerUserInfoField::GetUlDcm() const
|
||||
{
|
||||
NS_ASSERT_MSG(m_variant == TriggerFrameVariant::HE, "UL DCM flag only present in HE variant");
|
||||
return m_ulDcm;
|
||||
}
|
||||
|
||||
@@ -1545,7 +1583,8 @@ CtrlTriggerUserInfoField::GetMuBarTriggerDepUserInfo() const
|
||||
NS_OBJECT_ENSURE_REGISTERED(CtrlTriggerHeader);
|
||||
|
||||
CtrlTriggerHeader::CtrlTriggerHeader()
|
||||
: m_triggerType(TriggerFrameType::BASIC_TRIGGER),
|
||||
: m_variant(TriggerFrameVariant::HE),
|
||||
m_triggerType(TriggerFrameType::BASIC_TRIGGER),
|
||||
m_ulLength(0),
|
||||
m_moreTF(false),
|
||||
m_csRequired(false),
|
||||
@@ -1559,6 +1598,18 @@ CtrlTriggerHeader::CtrlTriggerHeader()
|
||||
CtrlTriggerHeader::CtrlTriggerHeader(TriggerFrameType type, const WifiTxVector& txVector)
|
||||
: CtrlTriggerHeader()
|
||||
{
|
||||
switch (txVector.GetPreambleType())
|
||||
{
|
||||
case WIFI_PREAMBLE_HE_TB:
|
||||
m_variant = TriggerFrameVariant::HE;
|
||||
break;
|
||||
case WIFI_PREAMBLE_EHT_TB:
|
||||
m_variant = TriggerFrameVariant::EHT;
|
||||
break;
|
||||
default:
|
||||
NS_ABORT_MSG("Cannot create a TF out of a TXVECTOR with preamble type: "
|
||||
<< txVector.GetPreambleType());
|
||||
}
|
||||
m_triggerType = type;
|
||||
SetUlBandwidth(txVector.GetChannelWidth());
|
||||
SetUlLength(txVector.GetLength());
|
||||
@@ -1594,6 +1645,7 @@ CtrlTriggerHeader::operator=(const CtrlTriggerHeader& trigger)
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_variant = trigger.m_variant;
|
||||
m_triggerType = trigger.m_triggerType;
|
||||
m_ulLength = trigger.m_ulLength;
|
||||
m_moreTF = trigger.m_moreTF;
|
||||
@@ -1635,6 +1687,20 @@ CtrlTriggerHeader::Print(std::ostream& os) const
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CtrlTriggerHeader::SetVariant(TriggerFrameVariant variant)
|
||||
{
|
||||
NS_ABORT_MSG_IF(!m_userInfoFields.empty(),
|
||||
"Cannot change Common Info field variant if User Info fields are present");
|
||||
m_variant = variant;
|
||||
}
|
||||
|
||||
TriggerFrameVariant
|
||||
CtrlTriggerHeader::GetVariant() const
|
||||
{
|
||||
return m_variant;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CtrlTriggerHeader::GetSerializedSize() const
|
||||
{
|
||||
@@ -1678,6 +1744,11 @@ CtrlTriggerHeader::Serialize(Buffer::Iterator start) const
|
||||
commonInfo |= (m_giAndLtfType & 0x03) << 20;
|
||||
commonInfo |= static_cast<uint64_t>(m_apTxPower & 0x3f) << 28;
|
||||
commonInfo |= static_cast<uint64_t>(m_ulSpatialReuse) << 37;
|
||||
if (m_variant == TriggerFrameVariant::HE)
|
||||
{
|
||||
uint64_t ulHeSigA2 = 0x01ff; // nine bits equal to 1
|
||||
commonInfo |= ulHeSigA2 << 54;
|
||||
}
|
||||
|
||||
i.WriteHtolsbU64(commonInfo);
|
||||
|
||||
@@ -1704,6 +1775,8 @@ CtrlTriggerHeader::Deserialize(Buffer::Iterator start)
|
||||
m_giAndLtfType = (commonInfo >> 20) & 0x03;
|
||||
m_apTxPower = (commonInfo >> 28) & 0x3f;
|
||||
m_ulSpatialReuse = (commonInfo >> 37) & 0xffff;
|
||||
uint8_t bit54and55 = (commonInfo >> 54) & 0x03;
|
||||
m_variant = bit54and55 == 3 ? TriggerFrameVariant::HE : TriggerFrameVariant::EHT;
|
||||
m_userInfoFields.clear();
|
||||
|
||||
NS_ABORT_MSG_IF(m_triggerType == TriggerFrameType::BFRP_TRIGGER,
|
||||
@@ -1844,7 +1917,7 @@ CtrlTriggerHeader::GetHeTbTxVector(uint16_t staId) const
|
||||
NS_ASSERT(userInfoIt != end());
|
||||
|
||||
WifiTxVector v;
|
||||
v.SetPreambleType(WifiPreamble::WIFI_PREAMBLE_HE_TB);
|
||||
v.SetPreambleType(userInfoIt->GetPreambleType());
|
||||
v.SetChannelWidth(GetUlBandwidth());
|
||||
v.SetGuardInterval(GetGuardInterval());
|
||||
v.SetLength(GetUlLength());
|
||||
@@ -2006,7 +2079,7 @@ CtrlTriggerHeader::GetCommonInfoField() const
|
||||
CtrlTriggerUserInfoField&
|
||||
CtrlTriggerHeader::AddUserInfoField()
|
||||
{
|
||||
m_userInfoFields.emplace_back(m_triggerType);
|
||||
m_userInfoFields.emplace_back(m_triggerType, m_variant);
|
||||
return m_userInfoFields.back();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define CTRL_HEADERS_H
|
||||
|
||||
#include "block-ack-type.h"
|
||||
#include "wifi-phy-common.h"
|
||||
|
||||
#include "ns3/he-ru.h"
|
||||
#include "ns3/header.h"
|
||||
@@ -567,6 +568,16 @@ enum class TriggerFrameType : uint8_t
|
||||
NFRP_TRIGGER = 7 // NDP Feedback Report Poll
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup wifi
|
||||
* The different variants for Common Info field and User Info field of Trigger Frames.
|
||||
*/
|
||||
enum class TriggerFrameVariant : uint8_t
|
||||
{
|
||||
HE = 0,
|
||||
EHT
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup wifi
|
||||
* \brief User Info field of Trigger frames.
|
||||
@@ -582,8 +593,9 @@ class CtrlTriggerUserInfoField
|
||||
* Constructor
|
||||
*
|
||||
* \param triggerType the Trigger frame type
|
||||
* \param variant the Trigger Frame variant
|
||||
*/
|
||||
CtrlTriggerUserInfoField(TriggerFrameType triggerType);
|
||||
CtrlTriggerUserInfoField(TriggerFrameType triggerType, TriggerFrameVariant variant);
|
||||
/**
|
||||
* Copy assignment operator.
|
||||
*
|
||||
@@ -632,6 +644,10 @@ class CtrlTriggerUserInfoField
|
||||
* \return the type of the Trigger Frame this User Info field belongs to
|
||||
*/
|
||||
TriggerFrameType GetType() const;
|
||||
/**
|
||||
* \return the preamble type of the TB PPDU solicited by this User Info field.
|
||||
*/
|
||||
WifiPreamble GetPreambleType() const;
|
||||
/**
|
||||
* Set the AID12 subfield, which carries the 12 LSBs of the AID of the
|
||||
* station for which this User Info field is intended. The whole AID can
|
||||
@@ -697,13 +713,15 @@ class CtrlTriggerUserInfoField
|
||||
*/
|
||||
uint8_t GetUlMcs() const;
|
||||
/**
|
||||
* Set the UL DCM subfield, which indicates whether or not DCM is used
|
||||
* Set the UL DCM subfield, which indicates whether or not DCM is used.
|
||||
* This method can only be used with HE variant User Info field.
|
||||
*
|
||||
* \param dcm whether to use DCM or not
|
||||
*/
|
||||
void SetUlDcm(bool dcm);
|
||||
/**
|
||||
* Get the UL DCM subfield, which indicates whether or not DCM is used
|
||||
* This method can only be used with HE variant User Info field.
|
||||
*
|
||||
* \return true if DCM is used
|
||||
*/
|
||||
@@ -831,11 +849,14 @@ class CtrlTriggerUserInfoField
|
||||
const CtrlBAckRequestHeader& GetMuBarTriggerDepUserInfo() const;
|
||||
|
||||
private:
|
||||
TriggerFrameVariant m_variant; //!< User Info field variant
|
||||
|
||||
uint16_t m_aid12; //!< Association ID of the addressed station
|
||||
uint8_t m_ruAllocation; //!< RU Allocation
|
||||
bool m_ulFecCodingType; //!< UL FEC Coding Type
|
||||
uint8_t m_ulMcs; //!< MCS to be used by the addressed station
|
||||
bool m_ulDcm; //!< whether or not to use Dual Carrier Modulation
|
||||
bool m_ulDcm; //!< whether or not to use Dual Carrier Modulation (HE variant only)
|
||||
bool m_ps160; //!< identifies the location of the RU (EHT variant only)
|
||||
|
||||
union {
|
||||
struct
|
||||
@@ -924,6 +945,21 @@ class CtrlTriggerHeader : public Header
|
||||
void Serialize(Buffer::Iterator start) const override;
|
||||
uint32_t Deserialize(Buffer::Iterator start) override;
|
||||
|
||||
/**
|
||||
* Set the Common Info field variant.
|
||||
*
|
||||
* For the moment, all User Info fields are of the same variant type, hence we
|
||||
* forbid changing the Common Info field variant type after adding User Info fields.
|
||||
*
|
||||
* \param variant the Common Info field variant
|
||||
*/
|
||||
void SetVariant(TriggerFrameVariant variant);
|
||||
/**
|
||||
* Get the Common Info field variant.
|
||||
*
|
||||
* \return the Common Info field variant
|
||||
*/
|
||||
TriggerFrameVariant GetVariant() const;
|
||||
/**
|
||||
* Set the Trigger frame type.
|
||||
*
|
||||
@@ -1244,6 +1280,7 @@ class CtrlTriggerHeader : public Header
|
||||
/**
|
||||
* Common Info field
|
||||
*/
|
||||
TriggerFrameVariant m_variant; //!< Common Info field variant
|
||||
TriggerFrameType m_triggerType; //!< Trigger type
|
||||
uint16_t m_ulLength; //!< Value for the L-SIG Length field
|
||||
bool m_moreTF; //!< True if a subsequent Trigger frame follows
|
||||
@@ -1252,6 +1289,7 @@ class CtrlTriggerHeader : public Header
|
||||
uint8_t m_giAndLtfType; //!< GI And LTF Type subfield
|
||||
uint8_t m_apTxPower; //!< Tx Power used by AP to transmit the Trigger Frame
|
||||
uint16_t m_ulSpatialReuse; //!< Value for the Spatial Reuse field in HE-SIG-A
|
||||
|
||||
/**
|
||||
* List of User Info fields
|
||||
*/
|
||||
|
||||
@@ -133,9 +133,10 @@ TestMultiUserScheduler::SelectTxFormat()
|
||||
(m_txFormat == SU_TX || m_txFormat == DL_MU_TX ? TriggerFrameType::BSRP_TRIGGER
|
||||
: TriggerFrameType::BASIC_TRIGGER);
|
||||
|
||||
m_trigger = CtrlTriggerHeader(ulTriggerType, m_txVector);
|
||||
|
||||
WifiTxVector txVector = m_txVector;
|
||||
txVector.SetPreambleType(WIFI_PREAMBLE_HE_TB);
|
||||
m_trigger = CtrlTriggerHeader(ulTriggerType, txVector);
|
||||
|
||||
txVector.SetGuardInterval(m_trigger.GetGuardInterval());
|
||||
|
||||
uint32_t ampduSize = (ulTriggerType == TriggerFrameType::BSRP_TRIGGER)
|
||||
|
||||
Reference in New Issue
Block a user