bug 1971: 802.11n at 2.4 GHz should include a signal extension duration

This commit is contained in:
Sébastien Deronne
2014-10-29 13:46:45 -07:00
parent 8fa5f0e741
commit e013980b83
7 changed files with 93 additions and 29 deletions

View File

@@ -95,7 +95,7 @@ AirtimeLinkMetricCalculator::CalculateMetric (Mac48Address peerAddress, Ptr<Mesh
//calculate metric
uint32_t metric = (uint32_t)((double)( /*Overhead + payload*/
mac->GetPifs () + mac->GetSlot () + mac->GetEifsNoDifs () + //DIFS + SIFS + AckTxTime = PIFS + SLOT + EifsNoDifs
mac->GetWifiPhy ()->CalculateTxDuration (m_testFrame->GetSize (), txVector, WIFI_PREAMBLE_LONG)
mac->GetWifiPhy ()->CalculateTxDuration (m_testFrame->GetSize (), txVector, WIFI_PREAMBLE_LONG, mac->GetWifiPhy ()->GetFrequency())
).GetMicroSeconds () / (10.24 * (1.0 - failAvg)));
return metric;
}

View File

@@ -982,7 +982,7 @@ MacLow::GetAckDuration (WifiTxVector ackTxVector) const
preamble= WIFI_PREAMBLE_HT_MF;
else
preamble=WIFI_PREAMBLE_LONG;
return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble);
return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble, m_phy->GetFrequency());
}
Time
MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
@@ -1000,7 +1000,7 @@ MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector,
preamble= WIFI_PREAMBLE_HT_MF;
else
preamble=WIFI_PREAMBLE_LONG;
return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble);
return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble, m_phy->GetFrequency());
}
Time
MacLow::GetCtsDuration (Mac48Address to, WifiTxVector rtsTxVector) const
@@ -1017,7 +1017,7 @@ MacLow::GetCtsDuration (WifiTxVector ctsTxVector) const
preamble= WIFI_PREAMBLE_HT_MF;
else
preamble=WIFI_PREAMBLE_LONG;
return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble, m_phy->GetFrequency());
}
uint32_t
MacLow::GetCtsSize (void) const
@@ -1105,7 +1105,7 @@ MacLow::CalculateOverallTxTime (Ptr<const Packet> packet,
{
preamble = WIFI_PREAMBLE_LONG;
}
txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency());
txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
txTime += Time (GetSifs () * 2);
}
@@ -1118,7 +1118,7 @@ MacLow::CalculateOverallTxTime (Ptr<const Packet> packet,
else
preamble=WIFI_PREAMBLE_LONG;
uint32_t dataSize = GetSize (packet, hdr);
txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble);
txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble, m_phy->GetFrequency());
if (params.MustWaitAck ())
{
txTime += GetSifs ();
@@ -1145,7 +1145,7 @@ MacLow::CalculateTransmissionTime (Ptr<const Packet> packet,
else
preamble=WIFI_PREAMBLE_LONG;
txTime += GetSifs ();
txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble);
txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble, m_phy->GetFrequency());
}
return txTime;
}
@@ -1183,7 +1183,7 @@ MacLow::NotifyNav (Ptr<const Packet> packet,const WifiMacHeader &hdr, WifiMode t
cts.SetType (WIFI_MAC_CTL_CTS);
WifiTxVector txVector=GetRtsTxVector (packet, &hdr);
Time navCounterResetCtsMissedDelay =
m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble) +
m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble, m_phy->GetFrequency()) +
Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
&MacLow::NavCounterResetCtsMissed, this,
@@ -1385,13 +1385,13 @@ MacLow::SendRtsForPacket (void)
duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector);
duration += GetSifs ();
duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
dataTxVector, preamble);
dataTxVector, preamble, m_phy->GetFrequency());
duration += GetSifs ();
duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
}
rts.SetDuration (duration);
Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency());
Time timerDelay = txDuration + GetCtsTimeout ();
NS_ASSERT (m_ctsTimeoutEvent.IsExpired ());
@@ -1419,7 +1419,7 @@ MacLow::StartDataTxTimers (WifiTxVector dataTxVector)
else
preamble=WIFI_PREAMBLE_LONG;
Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble);
Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble, m_phy->GetFrequency());
if (m_txParams.MustWaitNormalAck ())
{
Time timerDelay = txDuration + GetAckTimeout ();
@@ -1522,7 +1522,7 @@ MacLow::SendDataPacket (void)
{
duration += GetSifs ();
duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
dataTxVector, preamble);
dataTxVector, preamble, m_phy->GetFrequency());
if (m_txParams.MustWaitAck ())
{
duration += GetSifs ();
@@ -1582,7 +1582,7 @@ MacLow::SendCtsToSelf (void)
WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
duration += GetSifs ();
duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket,&m_currentHdr),
dataTxVector, preamble);
dataTxVector, preamble, m_phy->GetFrequency());
if (m_txParams.MustWaitBasicBlockAck ())
{
@@ -1603,7 +1603,7 @@ MacLow::SendCtsToSelf (void)
{
duration += GetSifs ();
duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
dataTxVector, preamble);
dataTxVector, preamble, m_phy->GetFrequency());
if (m_txParams.MustWaitCompressedBlockAck ())
{
duration += GetSifs ();
@@ -1626,7 +1626,7 @@ MacLow::SendCtsToSelf (void)
ForwardDown (packet, &cts, ctsTxVector,preamble);
Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble, m_phy->GetFrequency());
txDuration += GetSifs ();
NS_ASSERT (m_sendDataEvent.IsExpired ());
@@ -1697,7 +1697,7 @@ MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode)
newDuration += GetSifs ();
newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
dataTxVector, preamble);
dataTxVector, preamble, m_phy->GetFrequency());
duration -= txDuration;
duration -= GetSifs ();

View File

@@ -139,7 +139,7 @@ MinstrelWifiManager::SetupPhy (Ptr<WifiPhy> phy)
WifiMode mode = phy->GetMode (i);
WifiTxVector txVector;
txVector.SetMode(mode);
AddCalcTxTime (mode, phy->CalculateTxDuration (m_pktLen, txVector, WIFI_PREAMBLE_LONG));
AddCalcTxTime (mode, phy->CalculateTxDuration (m_pktLen, txVector, WIFI_PREAMBLE_LONG, phy->GetFrequency()));
}
WifiRemoteStationManager::SetupPhy (phy);
}

View File

@@ -329,7 +329,7 @@ WifiPhy::GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble
}
double
WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector)
WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector, double frequency)
{
WifiMode payloadMode=txvector.GetMode();
@@ -418,9 +418,15 @@ WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector)
double Nes=1;
// IEEE Std 802.11n, section 20.3.11, equation (20-32)
uint32_t numSymbols = lrint (m_Stbc*ceil ((16 + size * 8.0 + 6.0*Nes) / (m_Stbc* numDataBitsPerSymbol)));
return numSymbols * symbolDurationUs;
if (frequency >= 2400 && frequency <= 2500) //at 2.4 GHz
{
return (numSymbols * symbolDurationUs) + 6;
}
else //at 5 GHz
{
return (numSymbols * symbolDurationUs);
}
}
case WIFI_MOD_CLASS_DSSS:
// (Section 17.2.3.6 "Long PLCP LENGTH field"; IEEE Std 802.11-2012)
@@ -436,14 +442,14 @@ WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector)
}
Time
WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txvector, WifiPreamble preamble)
WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txvector, WifiPreamble preamble, double frequency)
{
WifiMode payloadMode=txvector.GetMode();
double duration = GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)
+ GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble)
+ GetPlcpHtSigHeaderDurationMicroSeconds (payloadMode, preamble)
+ GetPlcpHtTrainingSymbolDurationMicroSeconds (payloadMode, preamble,txvector)
+ GetPayloadDurationMicroSeconds (size, txvector);
+ GetPayloadDurationMicroSeconds (size, txvector, frequency);
return MicroSeconds (duration);
}

View File

@@ -281,10 +281,11 @@ public:
* \param size the number of bytes in the packet to send
* \param txvector the transmission parameters used for this packet
* \param preamble the type of preamble to use for this packet.
* \param frequency the channel center frequency (MHz)
* \return the total amount of time this PHY will stay busy for
* the transmission of these bytes.
*/
static Time CalculateTxDuration (uint32_t size, WifiTxVector txvector, enum WifiPreamble preamble);
static Time CalculateTxDuration (uint32_t size, WifiTxVector txvector, enum WifiPreamble preamble, double frequency);
/**
* \param payloadMode the WifiMode use for the transmission of the payload
@@ -337,10 +338,11 @@ public:
/**
* \param size the number of bytes in the packet to send
* \param txvector the transmission parameters used for this packet
* \param frequency the channel center frequency (MHz)
*
* \return the duration of the payload in microseconds
*/
static double GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector);
static double GetPayloadDurationMicroSeconds (uint32_t size, WifiTxVector txvector, double frequency);
/**
* The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used

View File

@@ -506,7 +506,7 @@ YansWifiPhy::StartReceivePacket (Ptr<Packet> packet,
NS_LOG_FUNCTION (this << packet << rxPowerDbm << txVector.GetMode()<< preamble);
rxPowerDbm += m_rxGainDb;
double rxPowerW = DbmToW (rxPowerDbm);
Time rxDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble);
Time rxDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble, GetFrequency());
WifiMode txMode = txVector.GetMode();
Time endRx = Simulator::Now () + rxDuration;
@@ -631,7 +631,7 @@ YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiTxVector txVector, WifiPr
return;
}
Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble);
Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble, GetFrequency());
if (m_state->IsStateRx ())
{
m_endRxEvent.Cancel ();

View File

@@ -29,6 +29,9 @@ using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("InterferenceHelperTxDurationTest");
static const double CHANNEL_1_MHZ = 2412.0; // a 2.4 GHz center frequency (MHz)
static const double CHANNEL_36_MHZ = 5180.0; // a 5 GHz center frequency (MHz)
class TxDurationTest : public TestCase
{
public:
@@ -80,7 +83,13 @@ TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint3
{
WifiTxVector txVector;
txVector.SetMode (payloadMode);
uint32_t calculatedDurationMicroSeconds = WifiPhy::GetPayloadDurationMicroSeconds (size, txVector);
double testedFrequency = CHANNEL_1_MHZ;
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_OFDM ||
payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
{
testedFrequency = CHANNEL_36_MHZ;
}
uint32_t calculatedDurationMicroSeconds = WifiPhy::GetPayloadDurationMicroSeconds (size, txVector, testedFrequency);
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
{
std::cerr << " size=" << size
@@ -90,6 +99,21 @@ TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint3
<< std::endl;
return false;
}
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
{
// Durations vary depending on frequency; test also 2.4 GHz (bug 1971)
testedFrequency = CHANNEL_1_MHZ;
calculatedDurationMicroSeconds = WifiPhy::GetPayloadDurationMicroSeconds (size, txVector, testedFrequency);
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds + 6)
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
<< std::endl;
return false;
}
}
return true;
}
@@ -101,7 +125,13 @@ TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamb
txVector.SetNss(1);
txVector.SetStbc(0);
txVector.SetNess(0);
double calculatedDurationMicroSeconds = WifiPhy::CalculateTxDuration (size, txVector, preamble).GetMicroSeconds ();
double testedFrequency = CHANNEL_1_MHZ;
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_OFDM ||
payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
{
testedFrequency = CHANNEL_36_MHZ;
}
double calculatedDurationMicroSeconds = WifiPhy::CalculateTxDuration (size, txVector, preamble, testedFrequency).GetMicroSeconds ();
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
{
std::cerr << " size=" << size
@@ -112,6 +142,22 @@ TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamb
<< std::endl;
return false;
}
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT)
{
// Durations vary depending on frequency; test also 2.4 GHz (bug 1971)
testedFrequency = CHANNEL_1_MHZ;
calculatedDurationMicroSeconds = WifiPhy::CalculateTxDuration (size, txVector, preamble, testedFrequency).GetMicroSeconds ();
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds + 6)
{
std::cerr << " size=" << size
<< " mode=" << payloadMode
<< " preamble=" << preamble
<< " known=" << knownDurationMicroSeconds
<< " calculated=" << calculatedDurationMicroSeconds
<< std::endl;
return false;
}
}
return true;
}
@@ -128,6 +174,7 @@ TxDurationTest::DoRun (void)
&& CheckPayloadDuration (1025, WifiPhy::GetDsssRate11Mbps (), 746)
&& CheckPayloadDuration (1026, WifiPhy::GetDsssRate11Mbps (), 747);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11b CCK duration failed");
// Similar, but we add PLCP preamble and header durations
// and we test different rates.
@@ -167,9 +214,12 @@ TxDurationTest::DoRun (void)
&& CheckTxDuration (1025, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 8200 + 192)
&& CheckTxDuration (1026, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 8208 + 192);
// values from http://mailman.isi.edu/pipermail/ns-developers/2009-July/006226.html
retval = retval && CheckTxDuration (14, WifiPhy::GetDsssRate1Mbps (), WIFI_PREAMBLE_LONG, 304);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11b duration failed");
// values from
// http://www.oreillynet.com/pub/a/wireless/2003/08/08/wireless_throughput.html
retval = retval
@@ -180,12 +230,16 @@ TxDurationTest::DoRun (void)
&& CheckTxDuration (76, WifiPhy::GetOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 32)
&& CheckTxDuration (14, WifiPhy::GetOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 24);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11a duration failed");
// 802.11g durations are same as 802.11a durations but with 6 us signal extension
retval = retval
&& CheckTxDuration (1536, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 254)
&& CheckTxDuration (76, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 38)
&& CheckTxDuration (14, WifiPhy::GetErpOfdmRate54Mbps (), WIFI_PREAMBLE_LONG, 30);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11g duration failed");
//802.11n durations
retval = retval
&& CheckTxDuration (1536,WifiPhy::GetOfdmRate65MbpsBW20MHz (), WIFI_PREAMBLE_HT_MF,228)
@@ -195,6 +249,8 @@ TxDurationTest::DoRun (void)
&& CheckTxDuration (1536, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF,218)
&& CheckTxDuration (76, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF,38)
&& CheckTxDuration (14, WifiPhy::GetOfdmRate65MbpsBW20MHzShGi (), WIFI_PREAMBLE_HT_GF,31);
NS_TEST_EXPECT_MSG_EQ (retval, true, "an 802.11n duration failed");
}
class TxDurationTestSuite : public TestSuite