diff --git a/src/wifi/model/ctrl-headers.cc b/src/wifi/model/ctrl-headers.cc index a33295462..ef39ce7ef 100644 --- a/src/wifi/model/ctrl-headers.cc +++ b/src/wifi/model/ctrl-headers.cc @@ -1305,6 +1305,8 @@ void CtrlTriggerUserInfoField::SetRuAllocation(HeRu::RuSpec ru) { NS_ABORT_MSG_IF(ru.GetIndex() == 0, "Valid indices start at 1"); + NS_ABORT_MSG_IF(m_triggerType == TriggerFrameType::MU_RTS_TRIGGER, + "SetMuRtsRuAllocation() must be used for MU-RTS"); switch (ru.GetRuType()) { @@ -1346,6 +1348,9 @@ CtrlTriggerUserInfoField::SetRuAllocation(HeRu::RuSpec ru) HeRu::RuSpec CtrlTriggerUserInfoField::GetRuAllocation() const { + NS_ABORT_MSG_IF(m_triggerType == TriggerFrameType::MU_RTS_TRIGGER, + "GetMuRtsRuAllocation() must be used for MU-RTS"); + HeRu::RuType ruType; std::size_t index; @@ -1396,6 +1401,39 @@ CtrlTriggerUserInfoField::GetRuAllocation() const return HeRu::RuSpec(ruType, index, primary80MHz); } +void +CtrlTriggerUserInfoField::SetMuRtsRuAllocation(uint8_t value) +{ + NS_ABORT_MSG_IF(m_triggerType != TriggerFrameType::MU_RTS_TRIGGER, + "SetMuRtsRuAllocation() can only be used for MU-RTS"); + NS_ABORT_MSG_IF( + value < 61 || value > 68, + "Value " + << +value + << " is not admitted for B7-B1 of the RU Allocation subfield of MU-RTS Trigger Frames"); + + m_ruAllocation = (value << 1); + if (value == 68) + { + // set B0 for 160 MHz and 80+80 MHz indication + m_ruAllocation++; + } +} + +uint8_t +CtrlTriggerUserInfoField::GetMuRtsRuAllocation() const +{ + NS_ABORT_MSG_IF(m_triggerType != TriggerFrameType::MU_RTS_TRIGGER, + "GetMuRtsRuAllocation() can only be used for MU-RTS"); + uint8_t value = (m_ruAllocation >> 1); + NS_ABORT_MSG_IF( + value < 61 || value > 68, + "Value " + << +value + << " is not admitted for B7-B1 of the RU Allocation subfield of MU-RTS Trigger Frames"); + return value; +} + void CtrlTriggerUserInfoField::SetUlFecCodingType(bool ldpc) { @@ -1599,6 +1637,9 @@ CtrlTriggerHeader::CtrlTriggerHeader() CtrlTriggerHeader::CtrlTriggerHeader(TriggerFrameType type, const WifiTxVector& txVector) : CtrlTriggerHeader() { + NS_ABORT_MSG_IF(m_triggerType == TriggerFrameType::MU_RTS_TRIGGER, + "This constructor cannot be used for MU-RTS"); + switch (txVector.GetPreambleType()) { case WIFI_PREAMBLE_HE_TB: @@ -1611,6 +1652,7 @@ CtrlTriggerHeader::CtrlTriggerHeader(TriggerFrameType type, const WifiTxVector& 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()); @@ -1914,6 +1956,8 @@ CtrlTriggerHeader::GetUlLength() const WifiTxVector CtrlTriggerHeader::GetHeTbTxVector(uint16_t staId) const { + NS_ABORT_MSG_IF(m_triggerType == TriggerFrameType::MU_RTS_TRIGGER, + "GetHeTbTxVector() cannot be used for MU-RTS"); auto userInfoIt = FindUserInfoWithAid(staId); NS_ASSERT(userInfoIt != end()); @@ -2167,6 +2211,11 @@ CtrlTriggerHeader::FindUserInfoWithRaRuUnassociated() const bool CtrlTriggerHeader::IsValid() const { + if (m_triggerType == TriggerFrameType::MU_RTS_TRIGGER) + { + return true; + } + // check that allocated RUs do not overlap // TODO This is not a problem in case of UL MU-MIMO std::vector prevRus; diff --git a/src/wifi/model/ctrl-headers.h b/src/wifi/model/ctrl-headers.h index 706829ce4..1c313718c 100644 --- a/src/wifi/model/ctrl-headers.h +++ b/src/wifi/model/ctrl-headers.h @@ -678,16 +678,54 @@ class CtrlTriggerUserInfoField bool HasRaRuForUnassociatedSta() const; /** * Set the RU Allocation subfield according to the specified RU. + * This method cannot be called on MU-RTS Trigger Frames (call SetMuRtsRuAllocation instead). * * \param ru the RU this User Info field is allocating */ void SetRuAllocation(HeRu::RuSpec ru); /** * Get the RU specified by the RU Allocation subfield. + * This method cannot be called on MU-RTS Trigger Frames (call GetMuRtsRuAllocation instead). * * \return the RU this User Info field is allocating */ HeRu::RuSpec GetRuAllocation() const; + /** + * Set the RU Allocation subfield based on the given value for the B7-B1 bits. + * This method can only be called on MU-RTS Trigger Frames. + * + * B7–B1 of the RU Allocation subfield is set to indicate the primary 20 MHz channel + * as follows: + * - 61 if the primary 20 MHz channel is the only 20 MHz channel or the lowest frequency + * 20 MHz channel in the primary 40 MHz channel or primary 80 MHz channel + * - 62 if the primary 20 MHz channel is the second lowest frequency 20 MHz channel in the + * primary 40 MHz channel or primary 80 MHz channel + * - 63 if the primary 20 MHz channel is the third lowest frequency 20 MHz channel in the + * primary 80 MHz channel + * - 64 if the primary 20 MHz channel is the fourth lowest frequency 20 MHz channel in the + * primary 80 MHz channel + * + * B7–B1 of the RU Allocation subfield is set to indicate the primary 40 MHz channel + * as follows: + * - 65 if the primary 40 MHz channel is the only 40 MHz channel or the lowest frequency + * 40 MHz channel in the primary 80 MHz channel + * - 66 if the primary 40 MHz channel is the second lowest frequency 40 MHz channel in the + * primary 80 MHz channel + * + * B7–B1 of the RU Allocation subfield is set to 67 to indicate the primary 80 MHz channel. + * + * B7–B1 of the RU Allocation subfield is set to 68 to indicate the primary and secondary + * 80 MHz channel. + * + * \param value the value for B7–B1 of the RU Allocation subfield + */ + void SetMuRtsRuAllocation(uint8_t value); + /** + * This method can only be called on MU-RTS Trigger Frames. + * + * \return the value of B7–B1 of the RU Allocation subfield (\see SetMuRtsRuAllocation) + */ + uint8_t GetMuRtsRuAllocation() const; /** * Set the UL FEC Coding Type subfield, which indicates whether BCC or LDPC is used * @@ -919,6 +957,8 @@ class CtrlTriggerHeader : public Header * UL MCS and SS Allocation subfields of each User Info field are set based * on the values stored in the corresponding entry of the HeMuUserInfoMap. * + * This constructor cannot be used to construct MU-RTS Trigger Frames. + * * \param type the Trigger frame type * \param txVector the TX vector used to build this Trigger Frame */