From 8f8f8acc07c02c276eff47223d1d9f8ecad85d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Fri, 27 Nov 2015 09:46:34 +0100 Subject: [PATCH] Bug 2193: Simulation fails when transmitting very small MPDU subframes --- RELEASE_NOTES | 1 + .../wireless/power-adaptation-distance.cc | 2 +- .../wireless/power-adaptation-interference.cc | 2 +- src/mesh/model/dot11s/airtime-metric.cc | 2 +- src/wifi/examples/test-interference-helper.cc | 4 +- src/wifi/examples/wifi-phy-test.cc | 6 +-- src/wifi/model/mac-low.cc | 43 ++++++++++--------- src/wifi/model/mac-low.h | 4 +- src/wifi/model/minstrel-wifi-manager.cc | 2 +- src/wifi/model/wifi-phy.cc | 32 +++++++++----- src/wifi/model/wifi-phy.h | 28 +++++++++++- src/wifi/model/yans-wifi-phy.cc | 6 +++ src/wifi/model/yans-wifi-phy.h | 1 + src/wifi/test/tx-duration-test.cc | 8 ++-- 14 files changed, 94 insertions(+), 47 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index ceac55911..c79018f4e 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -53,6 +53,7 @@ Bugs fixed - Bug 2176 - Building IPv4 address from char* doesn't look reliable - Bug 2183 - LiIonEnergySourceHelper is not in the energy wscript - Bug 2185 - WiFi MacLow may respond to errored frames that it should ignore +- Bug 2193 - Simulation fails when transmitting very small MPDU subframes - Bug 2195 - Udp[*]Client can't send packets to broadcast address - Bug 2201 - Simulation fails when active probing is used in 802.11n/ac with channel bonding enabled - Bug 2207 - Print node ID and time when printing routing tables diff --git a/examples/wireless/power-adaptation-distance.cc b/examples/wireless/power-adaptation-distance.cc index 53d6cc801..9c958e8cd 100644 --- a/examples/wireless/power-adaptation-distance.cc +++ b/examples/wireless/power-adaptation-distance.cc @@ -172,7 +172,7 @@ NodeStatistics::SetupPhy (Ptr phy) WifiMode mode = phy->GetMode (i); WifiTxVector txVector; txVector.SetMode (mode); - timeTable.push_back (std::make_pair (phy->CalculateTxDuration (packetSize, txVector, WIFI_PREAMBLE_LONG, phy->GetFrequency (), NORMAL_MPDU, 0), mode)); + timeTable.push_back (std::make_pair (phy->CalculateTxDuration (packetSize, txVector, WIFI_PREAMBLE_LONG, phy->GetFrequency ()), mode)); } } diff --git a/examples/wireless/power-adaptation-interference.cc b/examples/wireless/power-adaptation-interference.cc index 16596fa42..6e701f540 100644 --- a/examples/wireless/power-adaptation-interference.cc +++ b/examples/wireless/power-adaptation-interference.cc @@ -168,7 +168,7 @@ NodeStatistics::SetupPhy (Ptr phy) WifiMode mode = phy->GetMode (i); WifiTxVector txVector; txVector.SetMode (mode); - timeTable.push_back (std::make_pair (phy->CalculateTxDuration (packetSize, txVector, WIFI_PREAMBLE_LONG, phy->GetFrequency (), NORMAL_MPDU, 0), mode)); + timeTable.push_back (std::make_pair (phy->CalculateTxDuration (packetSize, txVector, WIFI_PREAMBLE_LONG, phy->GetFrequency ()), mode)); } } diff --git a/src/mesh/model/dot11s/airtime-metric.cc b/src/mesh/model/dot11s/airtime-metric.cc index 5cc6aba70..0f0b874a6 100644 --- a/src/mesh/model/dot11s/airtime-metric.cc +++ b/src/mesh/model/dot11s/airtime-metric.cc @@ -96,7 +96,7 @@ AirtimeLinkMetricCalculator::CalculateMetric (Mac48Address peerAddress, PtrGetPifs () + mac->GetSlot () + mac->GetEifsNoDifs () + //DIFS + SIFS + AckTxTime = PIFS + SLOT + EifsNoDifs - mac->GetWifiPhy ()->CalculateTxDuration (m_testFrame->GetSize (), txVector, WIFI_PREAMBLE_LONG, mac->GetWifiPhy ()->GetFrequency(), NORMAL_MPDU, 0) + mac->GetWifiPhy ()->CalculateTxDuration (m_testFrame->GetSize (), txVector, WIFI_PREAMBLE_LONG, mac->GetWifiPhy ()->GetFrequency()) ).GetMicroSeconds () / (10.24 * (1.0 - failAvg))); return metric; } diff --git a/src/wifi/examples/test-interference-helper.cc b/src/wifi/examples/test-interference-helper.cc index 15902aef7..49ca56791 100755 --- a/src/wifi/examples/test-interference-helper.cc +++ b/src/wifi/examples/test-interference-helper.cc @@ -106,7 +106,7 @@ InterferenceExperiment::SendA (void) const WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelA); txVector.SetMode (WifiMode (m_input.txModeA)); - m_txA->SendPacket (p, txVector, m_input.preamble, NORMAL_MPDU); + m_txA->SendPacket (p, txVector, m_input.preamble); } void @@ -116,7 +116,7 @@ InterferenceExperiment::SendB (void) const WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelB); txVector.SetMode (WifiMode (m_input.txModeB)); - m_txB->SendPacket (p, txVector, m_input.preamble, NORMAL_MPDU); + m_txB->SendPacket (p, txVector, m_input.preamble); } InterferenceExperiment::InterferenceExperiment () diff --git a/src/wifi/examples/wifi-phy-test.cc b/src/wifi/examples/wifi-phy-test.cc index bf794b7c9..58a67a3b0 100644 --- a/src/wifi/examples/wifi-phy-test.cc +++ b/src/wifi/examples/wifi-phy-test.cc @@ -74,7 +74,7 @@ PsrExperiment::Send (void) WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevel); txVector.SetMode (mode); - m_tx->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, NORMAL_MPDU); + m_tx->SendPacket (p, txVector, WIFI_PREAMBLE_LONG); } void @@ -182,7 +182,7 @@ CollisionExperiment::SendA (void) const WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelA); txVector.SetMode (WifiMode (m_input.txModeA)); - m_txA->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, NORMAL_MPDU); + m_txA->SendPacket (p, txVector, WIFI_PREAMBLE_LONG); } void @@ -193,7 +193,7 @@ CollisionExperiment::SendB (void) const WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelB); txVector.SetMode (WifiMode (m_input.txModeB)); - m_txB->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, NORMAL_MPDU); + m_txB->SendPacket (p, txVector, WIFI_PREAMBLE_LONG); } void diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc index 3ceb26267..84a0072fc 100644 --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -1252,7 +1252,7 @@ Time MacLow::GetAckDuration (WifiTxVector ackTxVector) const { NS_ASSERT (ackTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); //ACK should always use non-HT PPDU (HT PPDU cases not supported yet) - return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, WIFI_PREAMBLE_LONG, m_phy->GetFrequency (), NORMAL_MPDU, 0); + return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, WIFI_PREAMBLE_LONG, m_phy->GetFrequency ()); } Time @@ -1271,7 +1271,7 @@ MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, { preamble = WIFI_PREAMBLE_LONG; } - return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + return m_phy->CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxVector, preamble, m_phy->GetFrequency ()); } Time @@ -1285,7 +1285,7 @@ Time MacLow::GetCtsDuration (WifiTxVector ctsTxVector) const { NS_ASSERT (ctsTxVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT); //CTS should always use non-HT PPDU (HT PPDU cases not supported yet) - return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, WIFI_PREAMBLE_LONG, m_phy->GetFrequency (), NORMAL_MPDU, 0); + return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, WIFI_PREAMBLE_LONG, m_phy->GetFrequency ()); } uint32_t @@ -1385,7 +1385,7 @@ MacLow::CalculateOverallTxTime (Ptr packet, //Otherwise, RTS should always use non-HT PPDU (HT PPDU cases not supported yet) preamble = WIFI_PREAMBLE_LONG; } - txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency ()); txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector); txTime += Time (GetSifs () * 2); } @@ -1411,7 +1411,7 @@ MacLow::CalculateOverallTxTime (Ptr packet, preamble = WIFI_PREAMBLE_LONG; } uint32_t dataSize = GetSize (packet, hdr); - txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble, m_phy->GetFrequency ()); if (params.MustWaitAck ()) { txTime += GetSifs (); @@ -1451,7 +1451,7 @@ MacLow::CalculateTransmissionTime (Ptr packet, preamble = WIFI_PREAMBLE_LONG; } txTime += GetSifs (); - txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble, m_phy->GetFrequency ()); } return txTime; } @@ -1489,7 +1489,7 @@ MacLow::NotifyNav (Ptr packet,const WifiMacHeader &hdr, WifiPreamb cts.SetType (WIFI_MAC_CTL_CTS); WifiTxVector txVector = GetRtsTxVector (packet, &hdr); Time navCounterResetCtsMissedDelay = - m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0) + + m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, preamble, m_phy->GetFrequency ()) + Time (2 * GetSifs ()) + Time (2 * GetSlotTime ()); m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay, &MacLow::NavCounterResetCtsMissed, this, @@ -1585,7 +1585,7 @@ MacLow::ForwardDown (Ptr packet, const WifiMacHeader* hdr, ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec); if (!m_ampdu || hdr->IsRts ()) { - m_phy->SendPacket (packet, txVector, preamble, NORMAL_MPDU); + m_phy->SendPacket (packet, txVector, preamble); } else { @@ -1634,6 +1634,7 @@ MacLow::ForwardDown (Ptr packet, const WifiMacHeader* hdr, ampdutag.SetNoOfMpdus (queueSize); } newPacket->AddPacketTag (ampdutag); + if (delay == Seconds (0)) { if (!vhtSingleMpdu) @@ -1649,7 +1650,7 @@ MacLow::ForwardDown (Ptr packet, const WifiMacHeader* hdr, } else { - Simulator::Schedule (delay, &MacLow::SendPacket, this, newPacket, txVector, preamble, mpdutype); + Simulator::Schedule (delay, &MacLow::SendMpdu, this, newPacket, txVector, preamble, mpdutype); } if (queueSize > 1) { @@ -1661,7 +1662,7 @@ MacLow::ForwardDown (Ptr packet, const WifiMacHeader* hdr, } void -MacLow::SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, enum mpduType mpdutype) +MacLow::SendMpdu (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, enum mpduType mpdutype) { NS_LOG_DEBUG ("Sending MPDU as part of A-MPDU"); m_phy->SendPacket (packet, txVector, preamble, mpdutype); @@ -1794,7 +1795,7 @@ MacLow::SendRtsForPacket (void) duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector); duration += GetSifs (); duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), - dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + dataTxVector, preamble, m_phy->GetFrequency ()); duration += GetSifs (); if (m_txParams.MustWaitBasicBlockAck ()) { @@ -1813,7 +1814,7 @@ MacLow::SendRtsForPacket (void) if (m_txParams.HasNextPacket ()) { duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), - dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + dataTxVector, preamble, m_phy->GetFrequency ()); if (m_txParams.MustWaitAck ()) { duration += GetSifs (); @@ -1823,7 +1824,7 @@ MacLow::SendRtsForPacket (void) } rts.SetDuration (duration); - Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble, m_phy->GetFrequency ()); Time timerDelay = txDuration + GetCtsTimeout (); NS_ASSERT (m_ctsTimeoutEvent.IsExpired ()); @@ -1865,7 +1866,7 @@ MacLow::StartDataTxTimers (WifiTxVector dataTxVector) preamble = WIFI_PREAMBLE_LONG; } - Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble, m_phy->GetFrequency ()); if (m_txParams.MustWaitNormalAck ()) { Time timerDelay = txDuration + GetAckTimeout (); @@ -1983,7 +1984,7 @@ MacLow::SendDataPacket (void) { duration += GetSifs (); duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), - dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + dataTxVector, preamble, m_phy->GetFrequency ()); if (m_txParams.MustWaitAck ()) { duration += GetSifs (); @@ -2051,7 +2052,7 @@ MacLow::SendCtsToSelf (void) WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr); duration += GetSifs (); duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket,&m_currentHdr), - dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + dataTxVector, preamble, m_phy->GetFrequency ()); if (m_txParams.MustWaitBasicBlockAck ()) { @@ -2074,7 +2075,7 @@ MacLow::SendCtsToSelf (void) { duration += GetSifs (); duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), - dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + dataTxVector, preamble, m_phy->GetFrequency ()); if (m_txParams.MustWaitCompressedBlockAck ()) { duration += GetSifs (); @@ -2098,7 +2099,7 @@ MacLow::SendCtsToSelf (void) ForwardDown (packet, &cts, ctsTxVector,preamble); - Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble, m_phy->GetFrequency ()); txDuration += GetSifs (); NS_ASSERT (m_sendDataEvent.IsExpired ()); @@ -2209,7 +2210,7 @@ MacLow::SendDataAfterCts (Mac48Address source, Time duration) if (m_txParams.HasNextPacket ()) { newDuration += GetSifs (); - newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), dataTxVector, preamble, m_phy->GetFrequency ()); if (m_txParams.MustWaitCompressedBlockAck ()) { newDuration += GetSifs (); @@ -2223,7 +2224,7 @@ MacLow::SendDataAfterCts (Mac48Address source, Time duration) } } - Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0); + Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxVector, preamble, m_phy->GetFrequency ()); duration -= txDuration; duration -= GetSifs (); @@ -2836,7 +2837,7 @@ MacLow::StopMpduAggregation (Ptr peekedPacket, WifiMacHeader peeke } //An HT STA shall not transmit a PPDU that has a duration that is greater than aPPDUMaxTime (10 milliseconds) - if (m_phy->CalculateTxDuration (aggregatedPacket->GetSize () + peekedPacket->GetSize () + peekedHdr.GetSize () + WIFI_MAC_FCS_LENGTH, dataTxVector, preamble, m_phy->GetFrequency (), NORMAL_MPDU, 0) > MilliSeconds (10)) + if (m_phy->CalculateTxDuration (aggregatedPacket->GetSize () + peekedPacket->GetSize () + peekedHdr.GetSize () + WIFI_MAC_FCS_LENGTH, dataTxVector, preamble, m_phy->GetFrequency ()) > MilliSeconds (10)) { NS_LOG_DEBUG ("no more packets can be aggregated to satisfy PPDU <= aPPDUMaxTime"); return true; diff --git a/src/wifi/model/mac-low.h b/src/wifi/model/mac-low.h index b4a8fafe5..ef9d085f1 100644 --- a/src/wifi/model/mac-low.h +++ b/src/wifi/model/mac-low.h @@ -887,7 +887,7 @@ private: void ForwardDown (Ptr packet, const WifiMacHeader *hdr, WifiTxVector txVector, WifiPreamble preamble); /** - * Forward the packet down to WifiPhy for transmission. This is called for each MPDU when MPDU aggregation is used. + * Forward the MPDU down to WifiPhy for transmission. This is called for each MPDU when MPDU aggregation is used. * * \param packet * \param hdr @@ -895,7 +895,7 @@ private: * \param preamble * \param mpdutype */ - void SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, enum mpduType mpdutype); + void SendMpdu (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, enum mpduType mpdutype); /** * Return a TXVECTOR for the RTS frame given the destination. * The function consults WifiRemoteStationManager, which controls the rate diff --git a/src/wifi/model/minstrel-wifi-manager.cc b/src/wifi/model/minstrel-wifi-manager.cc index 9ca8079bb..c8b57b0c7 100644 --- a/src/wifi/model/minstrel-wifi-manager.cc +++ b/src/wifi/model/minstrel-wifi-manager.cc @@ -138,7 +138,7 @@ MinstrelWifiManager::SetupPhy (Ptr phy) WifiMode mode = phy->GetMode (i); WifiTxVector txVector; txVector.SetMode (mode); - AddCalcTxTime (mode, phy->CalculateTxDuration (m_pktLen, txVector, WIFI_PREAMBLE_LONG, phy->GetFrequency (), NORMAL_MPDU, 0)); + AddCalcTxTime (mode, phy->CalculateTxDuration (m_pktLen, txVector, WIFI_PREAMBLE_LONG, phy->GetFrequency ())); } WifiRemoteStationManager::SetupPhy (phy); } diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index bf417ec29..9377a7c61 100755 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -394,6 +394,12 @@ WifiPhy::GetPlcpPreambleDuration (WifiTxVector txVector, WifiPreamble preamble) } } +Time +WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble preamble, double frequency) +{ + return GetPayloadDuration (size, txVector, preamble, frequency, NORMAL_MPDU, 0); +} + Time WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble preamble, double frequency, enum mpduType mpdutype, uint8_t incFlag) { @@ -426,13 +432,12 @@ WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble //(Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012) //corresponds to N_{DBPS} in the table double numDataBitsPerSymbol = payloadMode.GetDataRate (txVector.GetChannelWidth (), 0, 1) * symbolDuration.GetNanoSeconds () / 1e9; - //(Section 18.3.5.4 "Pad bits (PAD)" Equation 18-11; IEEE Std 802.11-2012) - uint32_t numSymbols; + double numSymbols; if (mpdutype == MPDU_IN_AGGREGATE && preamble != WIFI_PREAMBLE_NONE) { //First packet in an A-MPDU - numSymbols = ceil ((16 + size * 8.0 + 6) / numDataBitsPerSymbol); + numSymbols = ((16 + size * 8.0 + 6) / numDataBitsPerSymbol); if (incFlag == 1) { m_totalAmpduSize += size; @@ -454,6 +459,7 @@ WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble //last packet in an A-MPDU uint32_t totalAmpduSize = m_totalAmpduSize + size; numSymbols = lrint (ceil ((16 + totalAmpduSize * 8.0 + 6) / numDataBitsPerSymbol)); + NS_ASSERT (m_totalAmpduNumSymbols <= numSymbols); numSymbols -= m_totalAmpduNumSymbols; if (incFlag == 1) { @@ -474,11 +480,11 @@ WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble //Add signal extension for ERP PHY if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM) { - return Time (numSymbols * symbolDuration) + MicroSeconds (6); + return NanoSeconds (numSymbols * symbolDuration.GetNanoSeconds ()) + MicroSeconds (6); } else { - return Time (numSymbols * symbolDuration); + return NanoSeconds (numSymbols * symbolDuration.GetNanoSeconds ()); } } case WIFI_MOD_CLASS_HT: @@ -520,13 +526,13 @@ WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble } //IEEE Std 802.11n, section 20.3.11, equation (20-32) - uint32_t numSymbols; double numDataBitsPerSymbol = payloadMode.GetDataRate (txVector.GetChannelWidth (), txVector.IsShortGuardInterval (), 1) * txVector.GetNss () * symbolDuration.GetNanoSeconds () / 1e9; + double numSymbols; if (mpdutype == MPDU_IN_AGGREGATE && preamble != WIFI_PREAMBLE_NONE) { //First packet in an A-MPDU - numSymbols = ceil (m_Stbc * (16 + size * 8.0 + 6 * Nes) / (m_Stbc * numDataBitsPerSymbol)); + numSymbols = (m_Stbc * (16 + size * 8.0 + 6 * Nes) / (m_Stbc * numDataBitsPerSymbol)); if (incFlag == 1) { m_totalAmpduSize += size; @@ -536,7 +542,7 @@ WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble else if (mpdutype == MPDU_IN_AGGREGATE && preamble == WIFI_PREAMBLE_NONE) { //consecutive packets in an A-MPDU - numSymbols = m_Stbc * ((size * 8.0 ) / (m_Stbc * numDataBitsPerSymbol)); + numSymbols = (m_Stbc * size * 8.0) / (m_Stbc * numDataBitsPerSymbol); if (incFlag == 1) { m_totalAmpduSize += size; @@ -568,11 +574,11 @@ WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT && frequency >= 2400 && frequency <= 2500 && ((mpdutype == NORMAL_MPDU && preamble != WIFI_PREAMBLE_NONE) || (mpdutype == LAST_MPDU_IN_AGGREGATE && preamble == WIFI_PREAMBLE_NONE))) //at 2.4 GHz { - return Time (numSymbols * symbolDuration) + MicroSeconds (6); + return NanoSeconds (numSymbols * symbolDuration.GetNanoSeconds ()) + MicroSeconds (6); } else //at 5 GHz { - return Time (numSymbols * symbolDuration); + return NanoSeconds (numSymbols * symbolDuration.GetNanoSeconds ()); } } case WIFI_MOD_CLASS_DSSS: @@ -609,6 +615,12 @@ WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, WifiPreamble return duration; } +Time +WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, WifiPreamble preamble, double frequency) +{ + return CalculateTxDuration (size, txVector, preamble, frequency, NORMAL_MPDU, 0); +} + void WifiPhy::NotifyTxBegin (Ptr packet) { diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index ad08b7a8b..943784503 100755 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -229,6 +229,14 @@ public: */ virtual void SetReceiveErrorCallback (RxErrorCallback callback) = 0; + /** + * \param packet the packet to send + * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send + * this packet, and txPowerLevel, a power level to use to send this packet. The real transmission + * power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels + * \param preamble the type of preamble to use to send this packet. + */ + virtual void SendPacket (Ptr packet, WifiTxVector txVector, enum WifiPreamble preamble) = 0; /** * \param packet the packet to send * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send @@ -310,6 +318,15 @@ public: */ virtual Time GetLastRxStartTime (void) const = 0; + /** + * \param size the number of bytes in the packet to send + * \param txVector the TXVECTOR used for the transmission of 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. + */ + Time CalculateTxDuration (uint32_t size, WifiTxVector txVector, enum WifiPreamble preamble, double frequency); /** * \param size the number of bytes in the packet to send * \param txVector the TXVECTOR used for the transmission of this packet @@ -396,6 +413,15 @@ public: * \return the duration of the PLCP preamble */ static Time GetPlcpPreambleDuration (WifiTxVector txVector, WifiPreamble preamble); + /** + * \param size the number of bytes in the packet to send + * \param txVector the TXVECTOR used for the transmission of this packet + * \param preamble the type of preamble to use for this packet + * \param frequency the channel center frequency (MHz) + * + * \return the duration of the payload + */ + Time GetPayloadDuration (uint32_t size, WifiTxVector txVector, WifiPreamble preamble, double frequency); /** * \param size the number of bytes in the packet to send * \param txVector the TXVECTOR used for the transmission of this packet @@ -1327,7 +1353,7 @@ private: TracedCallback, uint16_t, uint16_t, uint32_t, WifiPreamble, WifiTxVector, struct mpduInfo> m_phyMonitorSniffTxTrace; - uint32_t m_totalAmpduNumSymbols; //!< Number of symbols previously transmitted for the MPDUs in an A-MPDU, used for the computation of the number of symbols needed for the last MPDU in the A-MPDU + double m_totalAmpduNumSymbols; //!< Number of symbols previously transmitted for the MPDUs in an A-MPDU, used for the computation of the number of symbols needed for the last MPDU in the A-MPDU uint32_t m_totalAmpduSize; //!< Total size of the previously transmitted MPDUs in an A-MPDU, used for the computation of the number of symbols needed for the last MPDU in the A-MPDU }; diff --git a/src/wifi/model/yans-wifi-phy.cc b/src/wifi/model/yans-wifi-phy.cc index d5934d064..6d4fc4447 100644 --- a/src/wifi/model/yans-wifi-phy.cc +++ b/src/wifi/model/yans-wifi-phy.cc @@ -766,6 +766,12 @@ YansWifiPhy::StartReceivePacket (Ptr packet, } } +void +YansWifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble) +{ + SendPacket (packet, txVector, preamble, NORMAL_MPDU); +} + void YansWifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, enum mpduType mpdutype) { diff --git a/src/wifi/model/yans-wifi-phy.h b/src/wifi/model/yans-wifi-phy.h index a17cb291c..2172dbe50 100644 --- a/src/wifi/model/yans-wifi-phy.h +++ b/src/wifi/model/yans-wifi-phy.h @@ -279,6 +279,7 @@ public: virtual void SetReceiveOkCallback (WifiPhy::RxOkCallback callback); virtual void SetReceiveErrorCallback (WifiPhy::RxErrorCallback callback); + virtual void SendPacket (Ptr packet, WifiTxVector txVector, enum WifiPreamble preamble); virtual void SendPacket (Ptr packet, WifiTxVector txVector, enum WifiPreamble preamble, enum mpduType mpdutype); virtual void RegisterListener (WifiPhyListener *listener); virtual void UnregisterListener (WifiPhyListener *listener); diff --git a/src/wifi/test/tx-duration-test.cc b/src/wifi/test/tx-duration-test.cc index 5b94a8eff..2689f8dc8 100644 --- a/src/wifi/test/tx-duration-test.cc +++ b/src/wifi/test/tx-duration-test.cc @@ -100,7 +100,7 @@ TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint3 { testedFrequency = CHANNEL_36_MHZ; } - double calculatedDurationMicroSeconds = (double)phy->GetPayloadDuration (size, txVector, preamble, testedFrequency, NORMAL_MPDU, 0).GetMicroSeconds (); + double calculatedDurationMicroSeconds = (double)phy->GetPayloadDuration (size, txVector, preamble, testedFrequency).GetMicroSeconds (); if (calculatedDurationMicroSeconds != knownDurationMicroSeconds) { std::cerr << " size=" << size @@ -115,7 +115,7 @@ TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint3 { //Durations vary depending on frequency; test also 2.4 GHz (bug 1971) testedFrequency = CHANNEL_1_MHZ; - calculatedDurationMicroSeconds = (double)phy->GetPayloadDuration (size, txVector, preamble, testedFrequency, NORMAL_MPDU, 0).GetMicroSeconds (); + calculatedDurationMicroSeconds = (double)phy->GetPayloadDuration (size, txVector, preamble, testedFrequency).GetMicroSeconds (); if (calculatedDurationMicroSeconds != knownDurationMicroSeconds + 6) { std::cerr << " size=" << size @@ -148,7 +148,7 @@ TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, uint32_t c { testedFrequency = CHANNEL_36_MHZ; } - double calculatedDurationMicroSeconds = ((double)phy->CalculateTxDuration (size, txVector, preamble, testedFrequency, NORMAL_MPDU, 0).GetNanoSeconds ()) / 1000; + double calculatedDurationMicroSeconds = ((double)phy->CalculateTxDuration (size, txVector, preamble, testedFrequency).GetNanoSeconds ()) / 1000; if (calculatedDurationMicroSeconds != knownDurationMicroSeconds) { std::cerr << " size=" << size @@ -164,7 +164,7 @@ TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, uint32_t c { //Durations vary depending on frequency; test also 2.4 GHz (bug 1971) testedFrequency = CHANNEL_1_MHZ; - calculatedDurationMicroSeconds = ((double)phy->CalculateTxDuration (size, txVector, preamble, testedFrequency, NORMAL_MPDU, 0).GetNanoSeconds ()) / 1000; + calculatedDurationMicroSeconds = ((double)phy->CalculateTxDuration (size, txVector, preamble, testedFrequency).GetNanoSeconds ()) / 1000; if (calculatedDurationMicroSeconds != knownDurationMicroSeconds + 6) { std::cerr << " size=" << size