--- a/RELEASE_NOTES Mon Feb 06 20:31:02 2017 +0100
+++ b/RELEASE_NOTES Mon Feb 06 20:32:49 2017 +0100
@@ -82,6 +82,7 @@
- Bug 2613 - MaxRxSequence () is sometimes too large
- Bug 2607 - Minstrel HT manager results in an endless loop when a 802.11ac station is transmitting to a 802.11a access point
- Bug 2614 - RIP header version should be set to 2
+- Bug 2615 - When the TXOP limit is nonzero, packets should be fragmented so that the TXOP limit is not exceeded
- Bug 2627 - Ipv6RawSocket does not honor the bound interface when sending packets
- Bug 2628 - Simulation crashes because of an out of range TID
- Bug 2629 - Assert failure in MinstrelHtWifiManager::GetLowestIndex
--- a/src/wifi/model/dca-txop.cc Mon Feb 06 20:31:02 2017 +0100
+++ b/src/wifi/model/dca-txop.cc Mon Feb 06 20:32:49 2017 +0100
@@ -23,7 +23,6 @@
#include "dca-txop.h"
#include "dcf-manager.h"
#include "dcf-state.h"
-#include "mac-low.h"
#include "wifi-mac-queue.h"
#include "mac-tx-middle.h"
#include "random-stream.h"
@@ -181,28 +180,24 @@
uint32_t
DcaTxop::GetMinCw (void) const
{
- NS_LOG_FUNCTION (this);
return m_dcf->GetCwMin ();
}
uint32_t
DcaTxop::GetMaxCw (void) const
{
- NS_LOG_FUNCTION (this);
return m_dcf->GetCwMax ();
}
uint32_t
DcaTxop::GetAifsn (void) const
{
- NS_LOG_FUNCTION (this);
return m_dcf->GetAifsn ();
}
Time
DcaTxop::GetTxopLimit (void) const
{
- NS_LOG_FUNCTION (this);
return m_dcf->GetTxopLimit ();
}
@@ -375,19 +370,18 @@
", to=" << m_currentHdr.GetAddr1 () <<
", seq=" << m_currentHdr.GetSequenceControl ());
}
- MacLowTransmissionParameters params;
- params.DisableOverrideDurationId ();
+ m_currentParams.DisableOverrideDurationId ();
if (m_currentHdr.GetAddr1 ().IsGroup ())
{
- params.DisableRts ();
- params.DisableAck ();
- params.DisableNextData ();
- GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, params, this);
+ m_currentParams.DisableRts ();
+ m_currentParams.DisableAck ();
+ m_currentParams.DisableNextData ();
+ GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);
NS_LOG_DEBUG ("tx broadcast");
}
else
{
- params.EnableAck ();
+ m_currentParams.EnableAck ();
if (NeedFragmentation ())
{
@@ -396,19 +390,19 @@
if (IsLastFragment ())
{
NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
- params.DisableNextData ();
+ m_currentParams.DisableNextData ();
}
else
{
NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
- params.EnableNextData (GetNextFragmentSize ());
+ m_currentParams.EnableNextData (GetNextFragmentSize ());
}
- GetLow ()->StartTransmission (fragment, &hdr, params, this);
+ GetLow ()->StartTransmission (fragment, &hdr, m_currentParams, this);
}
else
{
- params.DisableNextData ();
- GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, params, this);
+ m_currentParams.DisableNextData ();
+ GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);
}
}
}
@@ -542,19 +536,18 @@
NextFragment ();
WifiMacHeader hdr;
Ptr<Packet> fragment = GetFragmentPacket (&hdr);
- MacLowTransmissionParameters params;
- params.EnableAck ();
- params.DisableRts ();
- params.DisableOverrideDurationId ();
+ m_currentParams.EnableAck ();
+ m_currentParams.DisableRts ();
+ m_currentParams.DisableOverrideDurationId ();
if (IsLastFragment ())
{
- params.DisableNextData ();
+ m_currentParams.DisableNextData ();
}
else
{
- params.EnableNextData (GetNextFragmentSize ());
+ m_currentParams.EnableNextData (GetNextFragmentSize ());
}
- GetLow ()->StartTransmission (fragment, &hdr, params, this);
+ GetLow ()->StartTransmission (fragment, &hdr, m_currentParams, this);
}
void
--- a/src/wifi/model/dca-txop.h Mon Feb 06 20:31:02 2017 +0100
+++ b/src/wifi/model/dca-txop.h Mon Feb 06 20:32:49 2017 +0100
@@ -21,6 +21,7 @@
#ifndef DCA_TXOP_H
#define DCA_TXOP_H
+#include "mac-low.h"
#include "wifi-mac-header.h"
#include "wifi-remote-station-manager.h"
@@ -29,7 +30,6 @@
class DcfState;
class DcfManager;
class WifiMacQueue;
-class MacLow;
class MacTxMiddle;
class RandomStream;
class CtrlBAckResponseHeader;
@@ -387,6 +387,7 @@
Ptr<const Packet> m_currentPacket;
WifiMacHeader m_currentHdr;
+ MacLowTransmissionParameters m_currentParams;
uint8_t m_fragmentNumber;
};
--- a/src/wifi/model/dcf-manager.h Mon Feb 06 20:31:02 2017 +0100
+++ b/src/wifi/model/dcf-manager.h Mon Feb 06 20:32:49 2017 +0100
@@ -31,6 +31,7 @@
class WifiPhy;
class PhyListener;
class DcfState;
+class MacLow;
/**
* \brief Manage a set of ns3::DcfState
--- a/src/wifi/model/edca-txop-n.cc Mon Feb 06 20:31:02 2017 +0100
+++ b/src/wifi/model/edca-txop-n.cc Mon Feb 06 20:32:49 2017 +0100
@@ -23,7 +23,6 @@
#include "ns3/log.h"
#include "ns3/pointer.h"
#include "edca-txop-n.h"
-#include "mac-low.h"
#include "dcf-manager.h"
#include "dcf-state.h"
#include "mac-tx-middle.h"
@@ -71,7 +70,8 @@
m_typeOfStation (STA),
m_blockAckType (COMPRESSED_BLOCK_ACK),
m_startTxop (Seconds (0)),
- m_isAccessRequestedForRts (false)
+ m_isAccessRequestedForRts (false),
+ m_currentIsFragmented (false)
{
NS_LOG_FUNCTION (this);
m_qosBlockedDestinations = new QosBlockedDestinations ();
@@ -183,6 +183,7 @@
{
NS_LOG_FUNCTION (this);
m_isAccessRequestedForRts = false;
+ m_startTxop = Simulator::Now ();
if (m_currentPacket == 0)
{
if (m_queue->IsEmpty () && !m_baManager->HasPackets ())
@@ -230,14 +231,13 @@
}
}
}
- MacLowTransmissionParameters params;
- params.DisableOverrideDurationId ();
+ m_currentParams.DisableOverrideDurationId ();
if (m_currentHdr.GetAddr1 ().IsGroup ())
{
- params.DisableRts ();
- params.DisableAck ();
- params.DisableNextData ();
- m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, this);
+ m_currentParams.DisableRts ();
+ m_currentParams.DisableAck ();
+ m_currentParams.DisableNextData ();
+ m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);
NS_LOG_DEBUG ("tx broadcast");
}
else if (m_currentHdr.GetType () == WIFI_MAC_CTL_BACKREQ)
@@ -248,35 +248,37 @@
{
if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ())
{
- params.DisableAck ();
+ m_currentParams.DisableAck ();
}
else
{
- params.EnableAck ();
+ m_currentParams.EnableAck ();
}
+ //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
if (((m_currentHdr.IsQosData () && !m_currentHdr.IsQosAmsdu ())
|| (m_currentHdr.IsData () && !m_currentHdr.IsQosData ()))
&& (m_blockAckThreshold == 0 || m_blockAckType == BASIC_BLOCK_ACK)
&& NeedFragmentation ())
{
- //With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
- params.DisableRts ();
+ m_currentIsFragmented = true;
+ m_currentParams.DisableRts ();
WifiMacHeader hdr;
Ptr<Packet> fragment = GetFragmentPacket (&hdr);
if (IsLastFragment ())
{
NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
- params.DisableNextData ();
+ m_currentParams.DisableNextData ();
}
else
{
NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
- params.EnableNextData (GetNextFragmentSize ());
+ m_currentParams.EnableNextData (GetNextFragmentSize ());
}
- m_low->StartTransmission (fragment, &hdr, params, this);
+ m_low->StartTransmission (fragment, &hdr, m_currentParams, this);
}
else
{
+ m_currentIsFragmented = false;
WifiMacHeader peekedHdr;
Time tstamp;
if (m_currentHdr.IsQosData ()
@@ -321,9 +323,8 @@
NS_LOG_DEBUG ("tx unicast A-MSDU");
}
}
- params.DisableNextData ();
- m_startTxop = Simulator::Now ();
- m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, this);
+ m_currentParams.DisableNextData ();
+ m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);
if (!GetAmpduExist (m_currentHdr.GetAddr1 ()))
{
CompleteTx ();
@@ -492,8 +493,8 @@
EdcaTxopN::GotAck (void)
{
NS_LOG_FUNCTION (this);
- if (!NeedFragmentation ()
- || IsLastFragment ()
+ if (!m_currentIsFragmented
+ || !m_currentParams.HasNextPacket ()
|| m_currentHdr.IsQosAmsdu ())
{
NS_LOG_DEBUG ("got ack. tx done.");
@@ -539,6 +540,18 @@
else
{
NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ());
+ if (!HasTxop ())
+ {
+ if (m_currentHdr.IsQosData () && GetTxopLimit () > NanoSeconds (0))
+ {
+ m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop);
+ m_cwTrace = m_dcf->GetCw ();
+ m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ());
+ m_dcf->StartBackoffNow (m_backoffTrace);
+ m_fragmentNumber++;
+ RestartAccessIfNeeded ();
+ }
+ }
}
}
@@ -731,7 +744,7 @@
void
EdcaTxopN::StartAccessIfNeeded (void)
{
- NS_LOG_FUNCTION (this);
+ //NS_LOG_FUNCTION (this);
if (m_currentPacket == 0
&& (!m_queue->IsEmpty () || m_baManager->HasPackets ())
&& !m_dcf->IsAccessRequested ())
@@ -821,18 +834,17 @@
}
return;
}
- MacLowTransmissionParameters params;
- params.DisableOverrideDurationId ();
- params.DisableNextData ();
+ m_currentParams.DisableOverrideDurationId ();
+ m_currentParams.DisableNextData ();
if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ())
{
- params.DisableAck ();
+ m_currentParams.DisableAck ();
}
else
{
- params.EnableAck ();
+ m_currentParams.EnableAck ();
}
- if (txopLimit >= GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, params))
+ if (txopLimit >= GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, m_currentParams))
{
NS_LOG_DEBUG ("start next packet");
m_currentPacket = m_queue->DequeueByTidAndAddress (&hdr,
@@ -849,7 +861,7 @@
m_currentHdr.SetNoRetry ();
m_fragmentNumber = 0;
VerifyBlockAck ();
- GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, params, this);
+ GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);
if (!GetAmpduExist (m_currentHdr.GetAddr1 ()))
{
CompleteTx ();
@@ -880,7 +892,7 @@
NS_LOG_FUNCTION (this);
WifiMacHeader hdr;
Time tstamp;
- if (!m_currentHdr.IsQosData ())
+ if (!m_currentHdr.IsQosData () || GetTxopLimit () == NanoSeconds (0))
{
return false;
}
@@ -895,8 +907,7 @@
return false;
}
- MacLowTransmissionParameters params;
- params.DisableOverrideDurationId ();
+ MacLowTransmissionParameters params = m_currentParams;
if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ())
{
params.DisableAck ();
@@ -948,8 +959,180 @@
//HT-delayed Block Ack agreement or when it is carried in an A-MPDU.
return false;
}
- return m_stationManager->NeedFragmentation (m_currentHdr.GetAddr1 (), &m_currentHdr,
- m_currentPacket);
+ bool needTxopFragmentation = false;
+ if (GetTxopLimit () > NanoSeconds (0) && m_currentHdr.IsData ())
+ {
+ needTxopFragmentation = (GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, m_currentParams) > GetTxopLimit ());
+ }
+ return (needTxopFragmentation || m_stationManager->NeedFragmentation (m_currentHdr.GetAddr1 (), &m_currentHdr, m_currentPacket));
+}
+
+bool
+EdcaTxopN::IsTxopFragmentation () const
+{
+ if (GetTxopLimit () == NanoSeconds (0))
+ {
+ return false;
+ }
+ if (!m_stationManager->NeedFragmentation (m_currentHdr.GetAddr1 (), &m_currentHdr, m_currentPacket)
+ || (GetTxopFragmentSize () < m_stationManager->GetFragmentSize (m_currentHdr.GetAddr1 (), &m_currentHdr,m_currentPacket, 0)))
+ {
+ return true;
+ }
+ return false;
+}
+
+uint32_t
+EdcaTxopN::GetTxopFragmentSize () const
+{
+ Time txopDuration = GetTxopLimit ();
+ if (txopDuration == NanoSeconds (0))
+ {
+ return 0;
+ }
+ uint32_t maxSize = m_currentPacket->GetSize ();
+ uint32_t minSize = 0;
+ uint32_t size;
+ bool found = false;
+ while (!found)
+ {
+ size = (minSize + ((maxSize - minSize) / 2));
+ if (GetLow ()->CalculateOverallTxFragmentTime (m_currentPacket, &m_currentHdr, m_currentParams, size) > txopDuration)
+ {
+ maxSize = size;
+ }
+ else
+ {
+ minSize = size;
+ }
+ if (GetLow ()->CalculateOverallTxFragmentTime (m_currentPacket, &m_currentHdr, m_currentParams, size) <= txopDuration
+ && GetLow ()->CalculateOverallTxFragmentTime (m_currentPacket, &m_currentHdr, m_currentParams, size + 1) > txopDuration)
+ {
+ found = true;
+ }
+ }
+ NS_ASSERT (size != 0);
+ return size;
+}
+
+uint32_t
+EdcaTxopN::GetNTxopFragment () const
+{
+ uint32_t fragmentSize = GetTxopFragmentSize ();
+ uint32_t nFragments = (m_currentPacket->GetSize () / fragmentSize);
+ if ((m_currentPacket->GetSize () % fragmentSize) > 0)
+ {
+ nFragments++;
+ }
+ NS_LOG_DEBUG ("GetNTxopFragment returning " << nFragments);
+ return nFragments;
+}
+
+uint32_t
+EdcaTxopN::GetTxopFragmentOffset (uint32_t fragmentNumber) const
+{
+ if (fragmentNumber == 0)
+ {
+ return 0;
+ }
+ uint32_t offset;
+ uint32_t fragmentSize = GetTxopFragmentSize ();
+ uint32_t nFragments = (m_currentPacket->GetSize () / fragmentSize);
+ if ((m_currentPacket->GetSize () % fragmentSize) > 0)
+ {
+ nFragments++;
+ }
+ if (fragmentNumber < nFragments)
+ {
+ offset = (fragmentNumber * fragmentSize);
+ }
+ else
+ {
+ NS_ASSERT (false);
+ }
+ NS_LOG_DEBUG ("GetTxopFragmentOffset returning " << offset);
+ return offset;
+}
+
+uint32_t
+EdcaTxopN::GetNextTxopFragmentSize (uint32_t fragmentNumber) const
+{
+ NS_LOG_FUNCTION (this << fragmentNumber);
+ uint32_t fragmentSize = GetTxopFragmentSize ();
+ uint32_t nFragments = GetNTxopFragment ();
+ if (fragmentNumber >= nFragments)
+ {
+ NS_LOG_DEBUG ("GetNextTxopFragmentSize returning 0");
+ return 0;
+ }
+ if (fragmentNumber == nFragments - 1)
+ {
+ fragmentSize = (m_currentPacket->GetSize () - ((nFragments - 1) * fragmentSize));
+ }
+ NS_LOG_DEBUG ("GetNextTxopFragmentSize returning " << fragmentSize);
+ return fragmentSize;
+}
+
+uint32_t
+EdcaTxopN::GetFragmentSize (void) const
+{
+ uint32_t size;
+ if (IsTxopFragmentation ())
+ {
+ size = GetNextTxopFragmentSize (m_fragmentNumber);
+ }
+ else
+ {
+ size = m_stationManager->GetFragmentSize (m_currentHdr.GetAddr1 (), &m_currentHdr,m_currentPacket, m_fragmentNumber);
+ }
+ return size;
+}
+
+uint32_t
+EdcaTxopN::GetNextFragmentSize (void) const
+ {
+ uint32_t size;
+ if (IsTxopFragmentation ())
+ {
+ size = GetNextTxopFragmentSize (m_fragmentNumber + 1);
+ }
+ else
+ {
+ size = m_stationManager->GetFragmentSize (m_currentHdr.GetAddr1 (), &m_currentHdr,m_currentPacket, m_fragmentNumber + 1);
+ }
+ return size;
+}
+
+uint32_t
+EdcaTxopN::GetFragmentOffset (void) const
+{
+ uint32_t offset;
+ if (IsTxopFragmentation ())
+ {
+ offset = GetTxopFragmentOffset (m_fragmentNumber);
+ }
+ else
+ {
+ offset = m_stationManager->GetFragmentOffset (m_currentHdr.GetAddr1 (), &m_currentHdr,
+ m_currentPacket, m_fragmentNumber);
+ }
+ return offset;
+}
+
+bool
+EdcaTxopN::IsLastFragment (void) const
+{
+ bool isLastFragment;
+ if (IsTxopFragmentation ())
+ {
+ isLastFragment = (m_fragmentNumber == GetNTxopFragment () - 1);
+ }
+ else
+ {
+ isLastFragment = m_stationManager->IsLastFragment (m_currentHdr.GetAddr1 (), &m_currentHdr,
+ m_currentPacket, m_fragmentNumber);
+ }
+ return isLastFragment;
}
Ptr<Packet>
@@ -1195,19 +1378,18 @@
m_currentPacket = bar.bar;
m_currentHdr = hdr;
- MacLowTransmissionParameters params;
- params.DisableRts ();
- params.DisableNextData ();
- params.DisableOverrideDurationId ();
+ m_currentParams.DisableRts ();
+ m_currentParams.DisableNextData ();
+ m_currentParams.DisableOverrideDurationId ();
if (bar.immediate)
{
if (m_blockAckType == BASIC_BLOCK_ACK)
{
- params.EnableBasicBlockAck ();
+ m_currentParams.EnableBasicBlockAck ();
}
else if (m_blockAckType == COMPRESSED_BLOCK_ACK)
{
- params.EnableCompressedBlockAck ();
+ m_currentParams.EnableCompressedBlockAck ();
}
else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
{
@@ -1217,9 +1399,9 @@
else
{
//Delayed block ack
- params.EnableAck ();
+ m_currentParams.EnableAck ();
}
- m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, this);
+ m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);
}
void
@@ -1307,13 +1489,12 @@
m_currentHdr.SetNoMoreFragments ();
m_currentHdr.SetNoRetry ();
- MacLowTransmissionParameters params;
- params.EnableAck ();
- params.DisableRts ();
- params.DisableNextData ();
- params.DisableOverrideDurationId ();
+ m_currentParams.EnableAck ();
+ m_currentParams.DisableRts ();
+ m_currentParams.DisableNextData ();
+ m_currentParams.DisableOverrideDurationId ();
- m_low->StartTransmission (m_currentPacket, &m_currentHdr, params, this);
+ m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this);
}
void
--- a/src/wifi/model/edca-txop-n.h Mon Feb 06 20:31:02 2017 +0100
+++ b/src/wifi/model/edca-txop-n.h Mon Feb 06 20:32:49 2017 +0100
@@ -463,6 +463,64 @@
* false otherwise.
*/
bool HasTxop (void) const;
+
+ /**
+ * Calculate the size of the next fragment.
+ *
+ * \return the size of the next fragment.
+ */
+ uint32_t GetNextFragmentSize (void) const;
+ /**
+ * Calculate the size of the current fragment.
+ *
+ * \return the size of the current fragment.
+ */
+ uint32_t GetFragmentSize (void) const;
+ /**
+ * Calculate the offset for the current fragment.
+ *
+ * \return the offset for the current fragment.
+ */
+ uint32_t GetFragmentOffset (void) const;
+ /**
+ * Check if the current fragment is the last fragment.
+ *
+ * \return true if the current fragment is the last fragment,
+ * false otherwise.
+ */
+ bool IsLastFragment (void) const;
+
+ /**
+ * Check if the current packet is fragmented because of an exceeded TXOP duration.
+ *
+ * \return true if the current packet is fragmented because of an exceeded TXOP duration,
+ * false otherwise
+ */
+ bool IsTxopFragmentation () const;
+ /**
+ * Calculate the size of the current TXOP fragment.
+ *
+ * \return the size of the current TXOP fragment
+ */
+ uint32_t GetTxopFragmentSize () const;
+ /**
+ * Calculate the number of TXOP fragments needed for the transmission of the current packet.
+ *
+ * \return the number of TXOP fragments needed for the transmission of the current packet
+ */
+ uint32_t GetNTxopFragment () const;
+ /**
+ * Calculate the size of the next TXOP fragment.
+ *
+ * \param fragmentNumber number of the next fragment
+ */
+ uint32_t GetNextTxopFragmentSize (uint32_t fragmentNumber) const;
+ /**
+ * Calculate the offset for the fragment.
+ *
+ * \param fragmentNumber number of the fragment
+ */
+ uint32_t GetTxopFragmentOffset (uint32_t fragmentNumber) const;
void DoDispose (void);
void DoInitialize (void);
@@ -480,6 +538,7 @@
Bar m_currentBar;
Time m_startTxop;
bool m_isAccessRequestedForRts;
+ bool m_currentIsFragmented;
TracedValue<uint32_t> m_backoffTrace;
TracedValue<uint32_t> m_cwTrace;
TracedCallback<Time, Time> m_txopTrace;
--- a/src/wifi/model/mac-low.cc Mon Feb 06 20:31:02 2017 +0100
+++ b/src/wifi/model/mac-low.cc Mon Feb 06 20:32:49 2017 +0100
@@ -24,6 +24,7 @@
#include "ns3/log.h"
#include "ns3/socket.h"
#include "mac-low.h"
+#include "edca-txop-n.h"
#include "wifi-mac-trailer.h"
#include "snr-tag.h"
#include "ampdu-tag.h"
@@ -892,10 +893,14 @@
NS_LOG_DEBUG ("receive ack from=" << m_currentHdr.GetAddr1 ());
SnrTag tag;
packet->RemovePacketTag (tag);
- m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
- rxSnr, txVector.GetMode ());
- m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
- rxSnr, txVector.GetMode (), tag.Get ());
+ //When fragmentation is used, only update manager when the last fragment is acknowledged
+ if (!m_txParams.HasNextPacket ())
+ {
+ m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
+ rxSnr, txVector.GetMode ());
+ m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
+ rxSnr, txVector.GetMode (), tag.Get ());
+ }
bool gotAck = false;
if (m_txParams.MustWaitNormalAck ()
&& m_normalAckTimeoutEvent.IsRunning ())
@@ -915,7 +920,7 @@
{
m_currentDca->GotAck ();
}
- if (m_txParams.HasNextPacket ())
+ if (m_txParams.HasNextPacket () && (!m_currentHdr.IsQosData () || m_currentDca->GetTxopLimit () == NanoSeconds (0) || m_currentDca->HasTxop ()))
{
if (m_stationManager->GetRifsPermitted ())
{
@@ -1322,6 +1327,32 @@
}
Time
+MacLow::CalculateOverallTxFragmentTime (Ptr<const Packet> packet,
+ const WifiMacHeader* hdr,
+ const MacLowTransmissionParameters& params,
+ uint32_t fragmentSize) const
+{
+ Time txTime = Seconds (0);
+ if (params.MustSendRts ())
+ {
+ WifiTxVector rtsTxVector = GetRtsTxVector (packet, hdr);
+ txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, m_phy->GetFrequency ());
+ txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
+ txTime += Time (GetSifs () * 2);
+ }
+ WifiTxVector dataTxVector = GetDataTxVector (packet, hdr);
+ Ptr<const Packet> fragment = Create<Packet> (fragmentSize);
+ uint32_t dataSize = GetSize (fragment, hdr);
+ txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, m_phy->GetFrequency ());
+ txTime += GetSifs ();
+ if (params.MustWaitAck ())
+ {
+ txTime += GetAckDuration (hdr->GetAddr1 (), dataTxVector);
+ }
+ return txTime;
+}
+
+Time
MacLow::CalculateTransmissionTime (Ptr<const Packet> packet,
const WifiMacHeader* hdr,
const MacLowTransmissionParameters& params) const
--- a/src/wifi/model/mac-low.h Mon Feb 06 20:31:02 2017 +0100
+++ b/src/wifi/model/mac-low.h Mon Feb 06 20:32:49 2017 +0100
@@ -24,7 +24,6 @@
#define MAC_LOW_H
#include "wifi-phy.h"
-#include "edca-txop-n.h"
#include "dcf-manager.h"
#include "wifi-remote-station-manager.h"
#include "block-ack-agreement.h"
@@ -39,6 +38,9 @@
namespace ns3 {
class WifiMacQueue;
+class DcaTxop;
+class EdcaTxopN;
+class DcfManager;
/**
* \brief control how a packet is transmitted.
@@ -451,6 +453,11 @@
Time CalculateOverallTxTime (Ptr<const Packet> packet,
const WifiMacHeader* hdr,
const MacLowTransmissionParameters ¶ms) const;
+
+ Time CalculateOverallTxFragmentTime (Ptr<const Packet> packet,
+ const WifiMacHeader* hdr,
+ const MacLowTransmissionParameters& params,
+ uint32_t fragmentSize) const;
/**
* \param packet packet to send