wifi: Serialize/deserialize PHY headers

This commit is contained in:
Sébastien Deronne
2022-11-28 19:02:41 +01:00
committed by Sébastien Deronne
parent 7179427b49
commit 7eb2e8d08a
14 changed files with 191 additions and 69 deletions

View File

@@ -89,15 +89,28 @@ EhtPpdu::IsUlMu() const
WifiTxVector
EhtPpdu::DoGetTxVector() const
{
auto phyHeaders = m_phyHeaders->Copy();
LSigHeader lSig;
if (phyHeaders->RemoveHeader(lSig) == 0)
{
NS_FATAL_ERROR("Missing L-SIG header in EHT PPDU");
}
// FIXME: define EHT PHY headers
HeSigHeader ehtPhyHdr;
if (phyHeaders->PeekHeader(ehtPhyHdr) == 0)
{
NS_FATAL_ERROR("Missing EHT PHY headers in EHT PPDU");
}
WifiTxVector txVector;
txVector.SetPreambleType(m_preamble);
txVector.SetMode(EhtPhy::GetEhtMcs(m_ehtSuMcs));
txVector.SetChannelWidth(m_heSig.GetChannelWidth());
txVector.SetChannelWidth(ehtPhyHdr.GetChannelWidth());
txVector.SetNss(m_ehtSuNStreams);
txVector.SetGuardInterval(m_heSig.GetGuardInterval());
txVector.SetBssColor(m_heSig.GetBssColor());
txVector.SetLength(m_lSig.GetLength());
txVector.SetGuardInterval(ehtPhyHdr.GetGuardInterval());
txVector.SetBssColor(ehtPhyHdr.GetBssColor());
txVector.SetLength(lSig.GetLength());
txVector.SetAggregation(m_psdus.size() > 1 || m_psdus.begin()->second->IsAggregate());
if (!m_muUserInfos.empty())
{
@@ -109,7 +122,7 @@ EhtPpdu::DoGetTxVector() const
}
if (ns3::IsDlMu(m_preamble))
{
txVector.SetSigBMode(HePhy::GetVhtMcs(m_heSig.GetMcs()));
txVector.SetSigBMode(HePhy::GetVhtMcs(ehtPhyHdr.GetMcs()));
txVector.SetRuAllocation(m_ruAllocation);
}
return txVector;

View File

@@ -106,6 +106,8 @@ void
HePpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
{
NS_LOG_FUNCTION(this << txVector << ppduDuration);
LSigHeader lSig;
uint8_t sigExtension = 0;
if (m_band == WIFI_PHY_BAND_2_4GHZ)
{
@@ -118,33 +120,52 @@ HePpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
4.0) *
3) -
3 - m);
m_lSig.SetLength(length);
lSig.SetLength(length);
HeSigHeader heSig;
if (ns3::IsDlMu(m_preamble))
{
m_heSig.SetMuFlag(true);
m_heSig.SetMcs(txVector.GetSigBMode().GetMcsValue());
heSig.SetMuFlag(true);
heSig.SetMcs(txVector.GetSigBMode().GetMcsValue());
}
else if (!ns3::IsUlMu(m_preamble))
{
m_heSig.SetMcs(txVector.GetMode().GetMcsValue());
m_heSig.SetNStreams(txVector.GetNss());
heSig.SetMcs(txVector.GetMode().GetMcsValue());
heSig.SetNStreams(txVector.GetNss());
}
m_heSig.SetBssColor(txVector.GetBssColor());
m_heSig.SetChannelWidth(m_channelWidth);
m_heSig.SetGuardIntervalAndLtfSize(txVector.GetGuardInterval(), 2 /*NLTF currently unused*/);
heSig.SetBssColor(txVector.GetBssColor());
heSig.SetChannelWidth(m_channelWidth);
heSig.SetGuardIntervalAndLtfSize(txVector.GetGuardInterval(), 2 /*NLTF currently unused*/);
m_phyHeaders->AddHeader(heSig);
m_phyHeaders->AddHeader(lSig);
}
WifiTxVector
HePpdu::DoGetTxVector() const
{
auto phyHeaders = m_phyHeaders->Copy();
LSigHeader lSig;
if (phyHeaders->RemoveHeader(lSig) == 0)
{
NS_FATAL_ERROR("Missing L-SIG header in HE PPDU");
}
HeSigHeader heSig;
if (phyHeaders->PeekHeader(heSig) == 0)
{
NS_FATAL_ERROR("Missing HE-SIG header in HE PPDU");
}
WifiTxVector txVector;
txVector.SetPreambleType(m_preamble);
txVector.SetMode(HePhy::GetHeMcs(m_heSig.GetMcs()));
txVector.SetChannelWidth(m_heSig.GetChannelWidth());
txVector.SetNss(m_heSig.GetNStreams());
txVector.SetGuardInterval(m_heSig.GetGuardInterval());
txVector.SetBssColor(m_heSig.GetBssColor());
txVector.SetLength(m_lSig.GetLength());
txVector.SetMode(HePhy::GetHeMcs(heSig.GetMcs()));
txVector.SetChannelWidth(heSig.GetChannelWidth());
txVector.SetNss(heSig.GetNStreams());
txVector.SetGuardInterval(heSig.GetGuardInterval());
txVector.SetBssColor(heSig.GetBssColor());
txVector.SetLength(lSig.GetLength());
txVector.SetAggregation(m_psdus.size() > 1 || m_psdus.begin()->second->IsAggregate());
for (const auto& muUserInfo : m_muUserInfos)
{
@@ -152,7 +173,7 @@ HePpdu::DoGetTxVector() const
}
if (txVector.IsDlMu())
{
txVector.SetSigBMode(HePhy::GetVhtMcs(m_heSig.GetMcs()));
txVector.SetSigBMode(HePhy::GetVhtMcs(heSig.GetMcs()));
txVector.SetRuAllocation(m_ruAllocation);
}
return txVector;
@@ -163,6 +184,10 @@ HePpdu::GetTxDuration() const
{
Time ppduDuration = Seconds(0);
const WifiTxVector& txVector = GetTxVector();
LSigHeader lSig;
m_phyHeaders->PeekHeader(lSig);
Time tSymbol = NanoSeconds(12800 + txVector.GetGuardInterval());
Time preambleDuration = WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
uint8_t sigExtension = 0;
@@ -173,7 +198,7 @@ HePpdu::GetTxDuration() const
uint8_t m = IsDlMu() ? 1 : 2;
// Equation 27-11 of IEEE P802.11ax/D4.0
Time calculatedDuration = MicroSeconds(
((ceil(static_cast<double>(m_lSig.GetLength() + 3 + m) / 3)) * 4) + 20 + sigExtension);
((ceil(static_cast<double>(lSig.GetLength() + 3 + m) / 3)) * 4) + 20 + sigExtension);
NS_ASSERT(calculatedDuration > preambleDuration);
uint32_t nSymbols =
floor(static_cast<double>((calculatedDuration - preambleDuration).GetNanoSeconds() -
@@ -229,17 +254,24 @@ HePpdu::GetPsdu(uint8_t bssColor, uint16_t staId /* = SU_STA_ID */) const
NS_ASSERT(m_psdus.size() == 1);
return m_psdus.at(SU_STA_ID);
}
else if (IsUlMu())
auto phyHeaders = m_phyHeaders->Copy();
LSigHeader lSig;
phyHeaders->RemoveHeader(lSig);
HeSigHeader heSig;
phyHeaders->RemoveHeader(heSig);
if (IsUlMu())
{
NS_ASSERT(m_psdus.size() == 1);
if (bssColor == 0 || m_heSig.GetBssColor() == 0 || (bssColor == m_heSig.GetBssColor()))
if (bssColor == 0 || heSig.GetBssColor() == 0 || (bssColor == heSig.GetBssColor()))
{
return m_psdus.begin()->second;
}
}
else
{
if (bssColor == 0 || m_heSig.GetBssColor() == 0 || (bssColor == m_heSig.GetBssColor()))
if (bssColor == 0 || heSig.GetBssColor() == 0 || (bssColor == heSig.GetBssColor()))
{
auto it = m_psdus.find(staId);
if (it != m_psdus.end())

View File

@@ -267,7 +267,6 @@ class HePpdu : public OfdmPpdu
*/
virtual void SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration);
HeSigHeader m_heSig; //!< the HE-SIG PHY header
mutable TxPsdFlag m_txPsdFlag; //!< the transmit power spectral density flag
WifiTxVector::HeMuUserInfoMap m_muUserInfos; //!< HE MU specific per-user information (to be

View File

@@ -54,6 +54,7 @@ void
HtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration, std::size_t psduSize)
{
NS_LOG_FUNCTION(this << txVector << ppduDuration << psduSize);
LSigHeader lSig;
uint8_t sigExtension = 0;
if (m_band == WIFI_PHY_BAND_2_4GHZ)
{
@@ -65,24 +66,43 @@ HtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration, std::size
4.0) *
3) -
3);
m_lSig.SetLength(length);
m_htSig.SetMcs(txVector.GetMode().GetMcsValue());
m_htSig.SetChannelWidth(m_channelWidth);
m_htSig.SetHtLength(psduSize);
m_htSig.SetAggregation(txVector.IsAggregation());
m_htSig.SetShortGuardInterval(txVector.GetGuardInterval() == 400);
lSig.SetLength(length);
HtSigHeader htSig;
htSig.SetMcs(txVector.GetMode().GetMcsValue());
htSig.SetChannelWidth(m_channelWidth);
htSig.SetHtLength(psduSize);
htSig.SetAggregation(txVector.IsAggregation());
htSig.SetShortGuardInterval(txVector.GetGuardInterval() == 400);
m_phyHeaders->AddHeader(htSig);
m_phyHeaders->AddHeader(lSig);
}
WifiTxVector
HtPpdu::DoGetTxVector() const
{
auto phyHeaders = m_phyHeaders->Copy();
LSigHeader lSig;
if (phyHeaders->RemoveHeader(lSig) == 0)
{
NS_FATAL_ERROR("Missing L-SIG header in HT PPDU");
}
HtSigHeader htSig;
if (phyHeaders->RemoveHeader(htSig) == 0)
{
NS_FATAL_ERROR("Missing HT-SIG header in HT PPDU");
}
WifiTxVector txVector;
txVector.SetPreambleType(m_preamble);
txVector.SetMode(HtPhy::GetHtMcs(m_htSig.GetMcs()));
txVector.SetChannelWidth(m_htSig.GetChannelWidth());
txVector.SetNss(1 + (m_htSig.GetMcs() / 8));
txVector.SetGuardInterval(m_htSig.GetShortGuardInterval() ? 400 : 800);
txVector.SetAggregation(m_htSig.GetAggregation());
txVector.SetMode(HtPhy::GetHtMcs(htSig.GetMcs()));
txVector.SetChannelWidth(htSig.GetChannelWidth());
txVector.SetNss(1 + (htSig.GetMcs() / 8));
txVector.SetGuardInterval(htSig.GetShortGuardInterval() ? 400 : 800);
txVector.SetAggregation(htSig.GetAggregation());
return txVector;
}
@@ -91,7 +111,14 @@ HtPpdu::GetTxDuration() const
{
Time ppduDuration = Seconds(0);
const WifiTxVector& txVector = GetTxVector();
ppduDuration = WifiPhy::CalculateTxDuration(m_htSig.GetHtLength(), txVector, m_band);
auto phyHeaders = m_phyHeaders->Copy();
LSigHeader lSig;
phyHeaders->RemoveHeader(lSig);
HtSigHeader htSig;
phyHeaders->RemoveHeader(htSig);
ppduDuration = WifiPhy::CalculateTxDuration(htSig.GetHtLength(), txVector, m_band);
return ppduDuration;
}

View File

@@ -165,9 +165,7 @@ class HtPpdu : public OfdmPpdu
* \param psduSize the size duration of the PHY payload (PSDU)
*/
void SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration, std::size_t psduSize);
HtSigHeader m_htSig; //!< the HT-SIG PHY header
}; // class HtPpdu
}; // class HtPpdu
} // namespace ns3

View File

@@ -47,17 +47,25 @@ void
DsssPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
{
NS_LOG_FUNCTION(this << txVector << ppduDuration);
m_dsssSig.SetRate(txVector.GetMode().GetDataRate(22));
DsssSigHeader dsssSig;
dsssSig.SetRate(txVector.GetMode().GetDataRate(22));
Time psduDuration = ppduDuration - WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
m_dsssSig.SetLength(psduDuration.GetMicroSeconds());
dsssSig.SetLength(psduDuration.GetMicroSeconds());
m_phyHeaders->AddHeader(dsssSig);
}
WifiTxVector
DsssPpdu::DoGetTxVector() const
{
DsssSigHeader dsssSig;
if (m_phyHeaders->PeekHeader(dsssSig) == 0)
{
NS_FATAL_ERROR("Missing DSSS SIG PHY header in DSSS PPDU");
}
WifiTxVector txVector;
txVector.SetPreambleType(m_preamble);
txVector.SetMode(DsssPhy::GetDsssRate(m_dsssSig.GetRate()));
txVector.SetMode(DsssPhy::GetDsssRate(dsssSig.GetRate()));
txVector.SetChannelWidth(22);
return txVector;
}
@@ -67,7 +75,9 @@ DsssPpdu::GetTxDuration() const
{
Time ppduDuration = Seconds(0);
const WifiTxVector& txVector = GetTxVector();
ppduDuration = MicroSeconds(m_dsssSig.GetLength()) +
DsssSigHeader dsssSig;
m_phyHeaders->PeekHeader(dsssSig);
ppduDuration = MicroSeconds(dsssSig.GetLength()) +
WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
return ppduDuration;
}

View File

@@ -124,9 +124,7 @@ class DsssPpdu : public WifiPpdu
* \param ppduDuration the transmission duration of this PPDU
*/
void SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration);
DsssSigHeader m_dsssSig; //!< the DSSS SIG PHY header
}; // class DsssPpdu
}; // class DsssPpdu
} // namespace ns3

View File

@@ -35,7 +35,7 @@ ErpOfdmPpdu::ErpOfdmPpdu(Ptr<const WifiPsdu> psdu,
uint16_t txCenterFreq,
WifiPhyBand band,
uint64_t uid)
: OfdmPpdu(psdu, txVector, txCenterFreq, band, uid, true) // instantiate LSigHeader of OfdmPpdu
: OfdmPpdu(psdu, txVector, txCenterFreq, band, uid, true) // add LSigHeader of OfdmPpdu
{
NS_LOG_FUNCTION(this << psdu << txVector << txCenterFreq << band << uid);
}
@@ -43,10 +43,16 @@ ErpOfdmPpdu::ErpOfdmPpdu(Ptr<const WifiPsdu> psdu,
WifiTxVector
ErpOfdmPpdu::DoGetTxVector() const
{
LSigHeader lSig;
if (m_phyHeaders->PeekHeader(lSig) == 0)
{
NS_FATAL_ERROR("Missing L-SIG in PPDU");
}
WifiTxVector txVector;
txVector.SetPreambleType(m_preamble);
NS_ASSERT(m_channelWidth == 20);
txVector.SetMode(ErpOfdmPhy::GetErpOfdmRate(m_lSig.GetRate()));
txVector.SetMode(ErpOfdmPhy::GetErpOfdmRate(lSig.GetRate()));
txVector.SetChannelWidth(m_channelWidth);
return txVector;
}

View File

@@ -53,18 +53,26 @@ void
OfdmPpdu::SetPhyHeaders(const WifiTxVector& txVector, std::size_t psduSize)
{
NS_LOG_FUNCTION(this << txVector << psduSize);
m_lSig.SetRate(txVector.GetMode().GetDataRate(txVector), m_channelWidth);
m_lSig.SetLength(psduSize);
LSigHeader lSig;
lSig.SetRate(txVector.GetMode().GetDataRate(txVector), m_channelWidth);
lSig.SetLength(psduSize);
m_phyHeaders->AddHeader(lSig);
}
WifiTxVector
OfdmPpdu::DoGetTxVector() const
{
LSigHeader lSig;
if (m_phyHeaders->PeekHeader(lSig) == 0)
{
NS_FATAL_ERROR("Missing L-SIG in PPDU");
}
WifiTxVector txVector;
txVector.SetPreambleType(m_preamble);
// OFDM uses 20 MHz, unless PHY channel width is 5 MHz or 10 MHz
uint16_t channelWidth = m_channelWidth < 20 ? m_channelWidth : 20;
txVector.SetMode(OfdmPhy::GetOfdmRate(m_lSig.GetRate(m_channelWidth), channelWidth));
txVector.SetMode(OfdmPhy::GetOfdmRate(lSig.GetRate(m_channelWidth), channelWidth));
txVector.SetChannelWidth(channelWidth);
return txVector;
}
@@ -74,7 +82,9 @@ OfdmPpdu::GetTxDuration() const
{
Time ppduDuration = Seconds(0);
const WifiTxVector& txVector = GetTxVector();
ppduDuration = WifiPhy::CalculateTxDuration(m_lSig.GetLength(), txVector, m_band);
LSigHeader lSig;
m_phyHeaders->PeekHeader(lSig);
ppduDuration = WifiPhy::CalculateTxDuration(lSig.GetLength(), txVector, m_band);
return ppduDuration;
}

View File

@@ -124,7 +124,6 @@ class OfdmPpdu : public WifiPpdu
protected:
WifiPhyBand m_band; //!< the WifiPhyBand used to transmit that PPDU
uint16_t m_channelWidth; //!< the channel width used to transmit that PPDU in MHz
LSigHeader m_lSig; //!< the L-SIG PHY header
private:
WifiTxVector DoGetTxVector() const override;

View File

@@ -53,14 +53,17 @@ void
VhtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
{
NS_LOG_FUNCTION(this << txVector << ppduDuration);
LSigHeader lSig;
uint16_t length =
((ceil((static_cast<double>(ppduDuration.GetNanoSeconds() - (20 * 1000)) / 1000) / 4.0) *
3) -
3);
m_lSig.SetLength(length);
m_vhtSig.SetMuFlag(m_preamble == WIFI_PREAMBLE_VHT_MU);
m_vhtSig.SetChannelWidth(m_channelWidth);
m_vhtSig.SetShortGuardInterval(txVector.GetGuardInterval() == 400);
lSig.SetLength(length);
VhtSigHeader vhtSig;
vhtSig.SetMuFlag(m_preamble == WIFI_PREAMBLE_VHT_MU);
vhtSig.SetChannelWidth(m_channelWidth);
vhtSig.SetShortGuardInterval(txVector.GetGuardInterval() == 400);
uint32_t nSymbols =
(static_cast<double>(
(ppduDuration - WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector))
@@ -68,21 +71,38 @@ VhtPpdu::SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration)
(3200 + txVector.GetGuardInterval()));
if (txVector.GetGuardInterval() == 400)
{
m_vhtSig.SetShortGuardIntervalDisambiguation((nSymbols % 10) == 9);
vhtSig.SetShortGuardIntervalDisambiguation((nSymbols % 10) == 9);
}
m_vhtSig.SetSuMcs(txVector.GetMode().GetMcsValue());
m_vhtSig.SetNStreams(txVector.GetNss());
vhtSig.SetSuMcs(txVector.GetMode().GetMcsValue());
vhtSig.SetNStreams(txVector.GetNss());
m_phyHeaders->AddHeader(vhtSig);
m_phyHeaders->AddHeader(lSig);
}
WifiTxVector
VhtPpdu::DoGetTxVector() const
{
auto phyHeaders = m_phyHeaders->Copy();
LSigHeader lSig;
if (phyHeaders->RemoveHeader(lSig) == 0)
{
NS_FATAL_ERROR("Missing L-SIG header in VHT PPDU");
}
VhtSigHeader vhtSig;
if (phyHeaders->RemoveHeader(vhtSig) == 0)
{
NS_FATAL_ERROR("Missing VHT-SIG header in VHT PPDU");
}
WifiTxVector txVector;
txVector.SetPreambleType(m_preamble);
txVector.SetMode(VhtPhy::GetVhtMcs(m_vhtSig.GetSuMcs()));
txVector.SetChannelWidth(m_vhtSig.GetChannelWidth());
txVector.SetNss(m_vhtSig.GetNStreams());
txVector.SetGuardInterval(m_vhtSig.GetShortGuardInterval() ? 400 : 800);
txVector.SetMode(VhtPhy::GetVhtMcs(vhtSig.GetSuMcs()));
txVector.SetChannelWidth(vhtSig.GetChannelWidth());
txVector.SetNss(vhtSig.GetNStreams());
txVector.SetGuardInterval(vhtSig.GetShortGuardInterval() ? 400 : 800);
txVector.SetAggregation(GetPsdu()->IsAggregate());
return txVector;
}
@@ -92,14 +112,21 @@ VhtPpdu::GetTxDuration() const
{
Time ppduDuration = Seconds(0);
const WifiTxVector& txVector = GetTxVector();
auto phyHeaders = m_phyHeaders->Copy();
LSigHeader lSig;
phyHeaders->RemoveHeader(lSig);
VhtSigHeader vhtSig;
phyHeaders->RemoveHeader(vhtSig);
Time tSymbol = NanoSeconds(3200 + txVector.GetGuardInterval());
Time preambleDuration = WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
Time calculatedDuration =
MicroSeconds(((ceil(static_cast<double>(m_lSig.GetLength() + 3) / 3)) * 4) + 20);
MicroSeconds(((ceil(static_cast<double>(lSig.GetLength() + 3) / 3)) * 4) + 20);
uint32_t nSymbols =
floor(static_cast<double>((calculatedDuration - preambleDuration).GetNanoSeconds()) /
tSymbol.GetNanoSeconds());
if (m_vhtSig.GetShortGuardInterval() && m_vhtSig.GetShortGuardIntervalDisambiguation())
if (vhtSig.GetShortGuardInterval() && vhtSig.GetShortGuardIntervalDisambiguation())
{
nSymbols--;
}

View File

@@ -179,8 +179,6 @@ class VhtPpdu : public OfdmPpdu
* \param ppduDuration the transmission duration of this PPDU
*/
void SetPhyHeaders(const WifiTxVector& txVector, Time ppduDuration);
VhtSigHeader m_vhtSig; //!< the VHT-SIG PHY header
}; // class VhtPpdu
} // namespace ns3

View File

@@ -37,6 +37,7 @@ WifiPpdu::WifiPpdu(Ptr<const WifiPsdu> psdu,
m_modulation(txVector.IsValid() ? txVector.GetModulationClass() : WIFI_MOD_CLASS_UNKNOWN),
m_txCenterFreq(txCenterFreq),
m_uid(uid),
m_phyHeaders(Create<Packet>()),
m_truncatedTx(false),
m_txPowerLevel(txVector.GetTxPowerLevel()),
m_txVector(txVector)
@@ -54,6 +55,7 @@ WifiPpdu::WifiPpdu(const WifiConstPsduMap& psdus,
: WIFI_MOD_CLASS_UNKNOWN),
m_txCenterFreq(txCenterFreq),
m_uid(uid),
m_phyHeaders(Create<Packet>()),
m_truncatedTx(false),
m_txPowerLevel(txVector.GetTxPowerLevel()),
m_txAntennas(txVector.GetNTx()),

View File

@@ -38,6 +38,7 @@
namespace ns3
{
class Packet;
class WifiPsdu;
/**
@@ -200,6 +201,8 @@ class WifiPpdu : public SimpleRefCount<WifiPpdu>
uint16_t m_txCenterFreq; //!< the center frequency (MHz) used for the transmission of this PPDU
uint64_t m_uid; //!< the unique ID of this PPDU
Ptr<Packet> m_phyHeaders; //!< the PHY headers contained in this PPDU
private:
/**
* Get the TXVECTOR used to send the PPDU.