wifi: Serialize/deserialize PHY headers
This commit is contained in:
committed by
Sébastien Deronne
parent
7179427b49
commit
7eb2e8d08a
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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--;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user