wifi: (fixes #2307) Get rid of m_receivedAtLeastOneMpdu flag

This commit is contained in:
Sébastien Deronne
2016-05-13 09:36:53 +02:00
parent 920777b0e3
commit 364ff63d7e
9 changed files with 109 additions and 103 deletions

View File

@@ -610,8 +610,8 @@ TracedCallbackTypedefTestCase::DoRun (void)
empty, empty, empty, empty);
CHECK (WifiPhyStateHelper::RxEndErrorTracedCallback,
Ptr<const Packet>, double, bool,
empty, empty);
Ptr<const Packet>, double,
empty, empty, empty);
CHECK (WifiPhyStateHelper::RxOkTracedCallback,
Ptr<const Packet>, double, WifiMode, WifiPreamble,

View File

@@ -15,7 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Ghada Badawy <gbadawy@gmail.com>
* Authors: Ghada Badawy <gbadawy@gmail.com>
* Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#include "ampdu-tag.h"
@@ -48,7 +49,9 @@ AmpduTag::GetInstanceTypeId (void) const
}
AmpduTag::AmpduTag ()
: m_ampdu (0)
: m_ampdu (0),
m_nbOfMpdus (0),
m_duration (Seconds(0))
{
}
@@ -59,30 +62,42 @@ AmpduTag::SetAmpdu (bool supported)
}
void
AmpduTag::SetNoOfMpdus (uint8_t noofmpdus)
AmpduTag::SetRemainingNbOfMpdus (uint8_t nbofmpdus)
{
NS_ASSERT (noofmpdus <= 64);
m_noOfMpdus = noofmpdus;
NS_ASSERT (nbofmpdus <= 64);
m_nbOfMpdus = nbofmpdus;
}
void
AmpduTag::SetRemainingAmpduDuration (Time duration)
{
NS_ASSERT (m_duration <= MilliSeconds(10));
m_duration = duration;
}
uint32_t
AmpduTag::GetSerializedSize (void) const
{
return 2;
return (2 + sizeof (Time));
}
void
AmpduTag::Serialize (TagBuffer i) const
{
i.WriteU8 (m_ampdu);
i.WriteU8 (m_noOfMpdus);
i.WriteU8 (m_nbOfMpdus);
int64_t duration = m_duration.GetTimeStep ();
i.Write ((const uint8_t *)&duration, sizeof(int64_t));
}
void
AmpduTag::Deserialize (TagBuffer i)
{
m_ampdu = i.ReadU8 ();
m_noOfMpdus = i.ReadU8 ();
m_nbOfMpdus = i.ReadU8 ();
int64_t duration;
i.Read ((uint8_t *)&duration, 8);
m_duration = Time (duration);
}
bool
@@ -92,15 +107,23 @@ AmpduTag::GetAmpdu () const
}
uint8_t
AmpduTag::GetNoOfMpdus () const
AmpduTag::GetRemainingNbOfMpdus () const
{
return m_noOfMpdus;
return m_nbOfMpdus;
}
Time
AmpduTag::GetRemainingAmpduDuration () const
{
return m_duration;
}
void
AmpduTag::Print (std::ostream &os) const
{
os << "A-MPDU exists=" << m_ampdu;
os << "A-MPDU exists=" << m_ampdu
<< " Remaining number of MPDUs=" << m_nbOfMpdus
<< " Remaining A-MPDU duration=" << m_duration;
}
} //namespace ns3

View File

@@ -15,13 +15,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Ghada Badawy <gbadawy@gmail.com>
* Authors: Ghada Badawy <gbadawy@gmail.com>
* Sébastien Deronne <sebastien.deronne@gmail.com>
*/
#ifndef AMPDU_TAG_H
#define AMPDU_TAG_H
#include "ns3/packet.h"
#include "ns3/nstime.h"
namespace ns3 {
@@ -48,11 +50,17 @@ public:
*/
void SetAmpdu (bool supported);
/**
* \param noofmpdus the number of MPDUs
* \param nbofmpdus the remaining number of MPDUs
*
* Set the number of MPDUs in the A-MPDU.
* Set the remaining number of MPDUs in the A-MPDU.
*/
void SetNoOfMpdus (uint8_t noofmpdus);
void SetRemainingNbOfMpdus (uint8_t nbofmpdus);
/**
* \param duration the remaining duration of the A-MPDU
*
* Set the remaining duration of the A-MPDU.
*/
void SetRemainingAmpduDuration (Time duration);
virtual void Serialize (TagBuffer i) const;
virtual void Deserialize (TagBuffer i);
@@ -67,15 +75,22 @@ public:
*/
bool GetAmpdu (void) const;
/**
* \return the number of MPDUs in an A-MPDU
* \return the remaining number of MPDUs in an A-MPDU
*
* Returns the number of MPDUs in an A-MPDU
* Returns the remaining number of MPDUs in an A-MPDU
*/
uint8_t GetNoOfMpdus (void) const;
uint8_t GetRemainingNbOfMpdus (void) const;
/**
* \return the remaining duration of an A-MPDU
*
* Returns the remaining duration of an A-MPDU
*/
Time GetRemainingAmpduDuration (void) const;
private:
uint8_t m_ampdu; //!< Flag whether it is an A-MPDU
uint8_t m_noOfMpdus; //!< number of MPDUs in the A-MPDU
uint8_t m_nbOfMpdus; //!< Remaining number of MPDUs in the A-MPDU
Time m_duration; //!< Remaining duration of the A-MPDU in nanoseconds
};
} //namespace ns3

View File

@@ -368,7 +368,6 @@ MacLow::MacLow ()
m_listener (0),
m_phyMacLowListener (0),
m_ctsToSelfSupported (false),
m_receivedAtLeastOneMpdu (false),
m_nTxMpdus (0)
{
NS_LOG_FUNCTION (this);
@@ -534,7 +533,7 @@ void
MacLow::ResetPhy (void)
{
m_phy->SetReceiveOkCallback (MakeNullCallback<void, Ptr<Packet>, double, WifiTxVector, enum WifiPreamble> ());
m_phy->SetReceiveErrorCallback (MakeNullCallback<void, Ptr<Packet>, double, bool> ());
m_phy->SetReceiveErrorCallback (MakeNullCallback<void, Ptr<Packet>, double> ());
RemovePhyMacLowListener (m_phy);
m_phy = 0;
}
@@ -779,7 +778,7 @@ MacLow::StartTransmission (Ptr<const Packet> packet,
{
AmpduTag ampdu;
m_currentPacket->PeekPacketTag (ampdu);
if (ampdu.GetNoOfMpdus () > 1)
if (ampdu.GetRemainingNbOfMpdus () > 0)
{
m_txParams.EnableCompressedBlockAck ();
}
@@ -839,39 +838,10 @@ MacLow::NeedCtsToSelf (void)
}
void
MacLow::ReceiveError (Ptr<Packet> packet, double rxSnr, bool isEndOfFrame)
MacLow::ReceiveError (Ptr<Packet> packet, double rxSnr)
{
NS_LOG_FUNCTION (this << packet << rxSnr << isEndOfFrame);
NS_LOG_FUNCTION (this << packet << rxSnr);
NS_LOG_DEBUG ("rx failed ");
if (isEndOfFrame == true && m_receivedAtLeastOneMpdu == true)
{
WifiMacHeader hdr;
AmpduTag ampdu;
if (packet->RemovePacketTag (ampdu))
{
MpduAggregator::DeaggregatedMpdus mpdu = MpduAggregator::Deaggregate (packet);
mpdu.begin ()->first->PeekHeader (hdr);
}
else
{
packet->PeekHeader (hdr);
}
if (hdr.GetAddr1 () != m_self)
{
NS_LOG_DEBUG ("hdr addr1 " << hdr.GetAddr1 () << "not for me (" << m_self << "); returning");
return;
}
NS_ASSERT (m_lastReceivedHdr.IsQosData ());
NS_LOG_DEBUG ("last a-mpdu subframe detected/sendImmediateBlockAck from=" << m_lastReceivedHdr.GetAddr2 ());
m_sendAckEvent = Simulator::Schedule (GetSifs (),
&MacLow::SendBlockAckAfterAmpdu, this,
m_lastReceivedHdr.GetQosTid (),
m_lastReceivedHdr.GetAddr2 (),
m_lastReceivedHdr.GetDuration (),
m_currentTxVector,
rxSnr);
m_receivedAtLeastOneMpdu = false;
}
if (m_txParams.MustWaitFastAck ())
{
NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ());
@@ -1064,7 +1034,8 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, Wifi
NS_ASSERT (i != m_bAckCaches.end ());
(*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
NS_ASSERT (m_sendAckEvent.IsExpired ());
//NS_ASSERT (m_sendAckEvent.IsExpired ());
m_sendAckEvent.Cancel ();
/* See section 11.5.3 in IEEE 802.11 for mean of this timer */
ResetBlockAckInactivityTimerIfNeeded (it->second.first);
if ((*it).second.first.IsImmediateBlockAck ())
@@ -1082,7 +1053,6 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, Wifi
{
NS_FATAL_ERROR ("Delayed block ack not supported.");
}
m_receivedAtLeastOneMpdu = false;
}
else
{
@@ -1097,7 +1067,6 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, Wifi
else if (hdr.IsCtl ())
{
NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
m_receivedAtLeastOneMpdu = false;
}
else if (hdr.GetAddr1 () == m_self)
{
@@ -1125,7 +1094,6 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, Wifi
hdr.GetDuration (),
txVector.GetMode (),
rxSnr);
m_receivedAtLeastOneMpdu = false;
}
else if (hdr.IsQosBlockAck ())
{
@@ -1176,7 +1144,6 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, Wifi
hdr.GetDuration (),
txVector.GetMode (),
rxSnr);
m_receivedAtLeastOneMpdu = false;
}
}
goto rxPacket;
@@ -1192,7 +1159,6 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, Wifi
if (hdr.IsData () || hdr.IsMgt ())
{
NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
m_receivedAtLeastOneMpdu = false;
goto rxPacket;
}
else
@@ -1677,6 +1643,7 @@ MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr,
AmpduTag ampdutag;
ampdutag.SetAmpdu (true);
Time delay = Seconds (0);
Time remainingAmpduDuration = m_phy->CalculateTxDuration (packet->GetSize (), txVector, preamble, m_phy->GetFrequency ());
if (queueSize > 1 || vhtSingleMpdu)
{
txVector.SetAggregation (true);
@@ -1695,10 +1662,7 @@ MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr,
}
listenerIt->second->GetMpduAggregator ()->AddHeaderAndPad (newPacket, last, vhtSingleMpdu);
ampdutag.SetNoOfMpdus (queueSize);
newPacket->AddPacketTag (ampdutag);
if (delay == Seconds (0))
{
if (!vhtSingleMpdu)
@@ -1710,6 +1674,17 @@ MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr,
{
mpdutype = NORMAL_MPDU;
}
}
Time mpduDuration = m_phy->CalculateTxDuration (newPacket->GetSize (), txVector, preamble, m_phy->GetFrequency (), mpdutype, 0);
remainingAmpduDuration -= mpduDuration;
ampdutag.SetRemainingNbOfMpdus (queueSize - 1);
ampdutag.SetRemainingAmpduDuration (remainingAmpduDuration);
newPacket->AddPacketTag (ampdutag);
if (delay == Seconds (0))
{
m_phy->SendPacket (newPacket, txVector, preamble, mpdutype);
}
else
@@ -1718,8 +1693,9 @@ MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr,
}
if (queueSize > 1)
{
delay = delay + m_phy->CalculateTxDuration (GetSize (newPacket, &newHdr), txVector, preamble, m_phy->GetFrequency (), mpdutype, 0);
delay = delay + mpduDuration;
}
preamble = WIFI_PREAMBLE_NONE;
}
}
@@ -2668,7 +2644,7 @@ MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Addre
StartDataTxTimers (blockAckReqTxVector);
}
NS_ASSERT (duration >= MicroSeconds (0));
NS_ASSERT (duration >= NanoSeconds (0));
hdr.SetDuration (duration);
//here should be present a control about immediate or delayed block ack
//for now we assume immediate
@@ -2813,7 +2789,6 @@ MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr,
if (aggregatedPacket->RemovePacketTag (ampdu))
{
ampduSubframe = true;
m_currentTxVector = txVector;
MpduAggregator::DeaggregatedMpdus packets = MpduAggregator::Deaggregate (aggregatedPacket);
MpduAggregator::DeaggregatedMpdusCI n = packets.begin ();
@@ -2829,13 +2804,19 @@ MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr,
NS_LOG_DEBUG ("Receive VHT single MPDU");
ampduSubframe = false;
}
else if (preamble != WIFI_PREAMBLE_NONE || !m_sendAckEvent.IsRunning ())
{
m_sendAckEvent = Simulator::Schedule (ampdu.GetRemainingAmpduDuration () + GetSifs (),
&MacLow::SendBlockAckAfterAmpdu, this,
firsthdr.GetQosTid (),
firsthdr.GetAddr2 (),
firsthdr.GetDuration (),
txVector,
rxSnr);
}
if (firsthdr.GetAddr1 () == m_self)
{
if (!vhtSingleMpdu)
{
m_receivedAtLeastOneMpdu = true;
}
if (firsthdr.IsAck () || firsthdr.IsBlockAck () || firsthdr.IsBlockAckReq ())
{
ReceiveOk ((*n).first, rxSnr, txVector, preamble, ampduSubframe);
@@ -2856,7 +2837,7 @@ MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr,
}
}
if (ampdu.GetNoOfMpdus () == 1 && !vhtSingleMpdu)
if (ampdu.GetRemainingNbOfMpdus () == 0 && !vhtSingleMpdu)
{
if (normalAck)
{
@@ -2869,24 +2850,16 @@ MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr,
AgreementsI it = m_bAckAgreements.find (std::make_pair (firsthdr.GetAddr2 (), tid));
if (it != m_bAckAgreements.end ())
{
NS_ASSERT (m_sendAckEvent.IsExpired ());
/* See section 11.5.3 in IEEE 802.11 for mean of this timer */
ResetBlockAckInactivityTimerIfNeeded (it->second.first);
NS_LOG_DEBUG ("rx A-MPDU/sendImmediateBlockAck from=" << firsthdr.GetAddr2 ());
m_sendAckEvent = Simulator::Schedule (GetSifs (),
&MacLow::SendBlockAckAfterAmpdu, this,
firsthdr.GetQosTid (),
firsthdr.GetAddr2 (),
firsthdr.GetDuration (),
txVector,
rxSnr);
NS_ASSERT (m_sendAckEvent.IsRunning ());
}
else
{
NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
}
}
m_receivedAtLeastOneMpdu = false;
}
}
else
@@ -3173,16 +3146,19 @@ MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr)
listenerIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
currentAggregatedPacket->AddHeader (blockAckReq);
}
if (qosPolicy == 0)
{
listenerIt->second->CompleteTransfer (hdr.GetAddr1 (), tid);
}
//Add packet tag
AmpduTag ampdutag;
ampdutag.SetAmpdu (true);
ampdutag.SetNoOfMpdus (i);
ampdutag.SetRemainingNbOfMpdus (i - 1);
newPacket = currentAggregatedPacket;
newPacket->AddPacketTag (ampdutag);
NS_LOG_DEBUG ("tx unicast A-MPDU");
listenerIt->second->SetAmpdu (hdr.GetAddr1 (), true);
}
@@ -3217,8 +3193,6 @@ MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr)
//Add packet tag
AmpduTag ampdutag;
ampdutag.SetAmpdu (true);
ampdutag.SetNoOfMpdus (1);
newPacket = currentAggregatedPacket;
newPacket->AddHeader (peekedHdr);
WifiMacTrailer fcs;

View File

@@ -736,7 +736,7 @@ public:
* This method is typically invoked by the lower PHY layer to notify
* the MAC layer that a packet was unsuccessfully received.
*/
void ReceiveError (Ptr<Packet> packet, double rxSnr, bool isEndOfFrame);
void ReceiveError (Ptr<Packet> packet, double rxSnr);
/**
* \param duration switching delay duration.
*
@@ -1378,7 +1378,6 @@ private:
uint8_t m_sentMpdus; //!< Number of transmitted MPDUs in an A-MPDU that have not been acknowledged yet
Ptr<WifiMacQueue> m_aggregateQueue; //!< Queue used for MPDU aggregation
WifiTxVector m_currentTxVector; //!< TXVECTOR used for the current packet transmission
bool m_receivedAtLeastOneMpdu; //!< Flag whether an MPDU has already been successfully received while receiving an A-MPDU
std::vector<Item> m_txPackets; //!< Contain temporary items to be sent with the next A-MPDU transmission, once RTS/CTS exchange has succeeded. It is not used in other cases.
uint32_t m_nTxMpdus; //!<Holds the number of transmitted MPDUs in the last A-MPDU transmission
};

View File

@@ -442,14 +442,14 @@ WifiPhyStateHelper::SwitchFromRxEndOk (Ptr<Packet> packet, double snr, WifiTxVec
}
void
WifiPhyStateHelper::SwitchFromRxEndError (Ptr<Packet> packet, double snr, bool isEndOfFrame)
WifiPhyStateHelper::SwitchFromRxEndError (Ptr<Packet> packet, double snr)
{
m_rxErrorTrace (packet, snr);
NotifyRxEndError ();
DoSwitchFromRx ();
if (!m_rxErrorCallback.IsNull ())
{
m_rxErrorCallback (packet, snr, isEndOfFrame);
m_rxErrorCallback (packet, snr);
}
}

View File

@@ -167,9 +167,8 @@ public:
*
* \param packet the packet that we failed to received
* \param snr the SNR of the received packet
* \param isEndOfFrame PHY-RXEND indication.
*/
void SwitchFromRxEndError (Ptr<Packet> packet, double snr, bool isEndOfFrame);
void SwitchFromRxEndError (Ptr<Packet> packet, double snr);
/**
* Switch to CCA busy.
*
@@ -217,10 +216,9 @@ public:
*
* \param [in] packet The received packet.
* \param [in] snr The SNR of the received packet.
* \param [in] isEndOfFrame PHY-RXEND indication..
*/
typedef void (* RxEndErrorTracedCallback)
(Ptr<const Packet> packet, double snr, bool isEndOfFrame);
(Ptr<const Packet> packet, double snr);
/**
* TracedCallback signature for transmit event.

View File

@@ -192,9 +192,8 @@ public:
/**
* arg1: packet received unsuccessfully
* arg2: snr of packet
* arg3: PHY-RXEND flag
*/
typedef Callback<void, Ptr<Packet>, double, bool> RxErrorCallback;
typedef Callback<void, Ptr<Packet>, double> RxErrorCallback;
static TypeId GetTypeId (void);

View File

@@ -655,16 +655,16 @@ YansWifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet,
else if (preamble != WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum == 0)
{
//received the first MPDU in an MPDU
m_mpdusNum = ampduTag.GetNoOfMpdus () - 1;
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
m_rxMpduReferenceNumber++;
}
else if (preamble == WIFI_PREAMBLE_NONE && packet->PeekPacketTag (ampduTag) && m_mpdusNum > 0)
{
//received the other MPDUs that are part of the A-MPDU
if (ampduTag.GetNoOfMpdus () < m_mpdusNum)
if (ampduTag.GetRemainingNbOfMpdus () < (m_mpdusNum - 1))
{
NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetNoOfMpdus ());
m_mpdusNum = ampduTag.GetNoOfMpdus ();
NS_LOG_DEBUG ("Missing MPDU from the A-MPDU " << m_mpdusNum - ampduTag.GetRemainingNbOfMpdus ());
m_mpdusNum = ampduTag.GetRemainingNbOfMpdus ();
}
else
{
@@ -1235,14 +1235,12 @@ YansWifiPhy::EndReceive (Ptr<Packet> packet, enum WifiPreamble preamble, enum mp
{
/* failure. */
NotifyRxDrop (packet);
bool isEndOfFrame = ((mpdutype == NORMAL_MPDU && preamble != WIFI_PREAMBLE_NONE) || (mpdutype == LAST_MPDU_IN_AGGREGATE && preamble == WIFI_PREAMBLE_NONE));
m_state->SwitchFromRxEndError (packet, snrPer.snr, isEndOfFrame);
m_state->SwitchFromRxEndError (packet, snrPer.snr);
}
}
else
{
bool isEndOfFrame = ((mpdutype == NORMAL_MPDU && preamble != WIFI_PREAMBLE_NONE) || (mpdutype == LAST_MPDU_IN_AGGREGATE && preamble == WIFI_PREAMBLE_NONE));
m_state->SwitchFromRxEndError (packet, snrPer.snr, isEndOfFrame);
m_state->SwitchFromRxEndError (packet, snrPer.snr);
}
if (preamble == WIFI_PREAMBLE_NONE && mpdutype == LAST_MPDU_IN_AGGREGATE)