diff --git a/src/test/traced/traced-callback-typedef-test-suite.cc b/src/test/traced/traced-callback-typedef-test-suite.cc index ab1a7040a..775412bf7 100644 --- a/src/test/traced/traced-callback-typedef-test-suite.cc +++ b/src/test/traced/traced-callback-typedef-test-suite.cc @@ -610,8 +610,8 @@ TracedCallbackTypedefTestCase::DoRun (void) empty, empty, empty, empty); CHECK (WifiPhyStateHelper::RxEndErrorTracedCallback, - Ptr, double, bool, - empty, empty); + Ptr, double, + empty, empty, empty); CHECK (WifiPhyStateHelper::RxOkTracedCallback, Ptr, double, WifiMode, WifiPreamble, diff --git a/src/wifi/model/ampdu-tag.cc b/src/wifi/model/ampdu-tag.cc index 1e9394961..fe3fc747f 100644 --- a/src/wifi/model/ampdu-tag.cc +++ b/src/wifi/model/ampdu-tag.cc @@ -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 + * Authors: Ghada Badawy + * Sébastien Deronne */ #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 diff --git a/src/wifi/model/ampdu-tag.h b/src/wifi/model/ampdu-tag.h index 201f992ba..7e4ddc903 100644 --- a/src/wifi/model/ampdu-tag.h +++ b/src/wifi/model/ampdu-tag.h @@ -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 + * Authors: Ghada Badawy + * Sébastien Deronne */ #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 diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc index 884bb0308..e946e9c6d 100644 --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -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, double, WifiTxVector, enum WifiPreamble> ()); - m_phy->SetReceiveErrorCallback (MakeNullCallback, double, bool> ()); + m_phy->SetReceiveErrorCallback (MakeNullCallback, double> ()); RemovePhyMacLowListener (m_phy); m_phy = 0; } @@ -779,7 +778,7 @@ MacLow::StartTransmission (Ptr 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, double rxSnr, bool isEndOfFrame) +MacLow::ReceiveError (Ptr 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, 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, 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, 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, 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, double rxSnr, WifiTxVector txVector, Wifi hdr.GetDuration (), txVector.GetMode (), rxSnr); - m_receivedAtLeastOneMpdu = false; } } goto rxPacket; @@ -1192,7 +1159,6 @@ MacLow::ReceiveOk (Ptr 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 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 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 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 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 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 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 aggregatedPacket, double rxSnr, } } - if (ampdu.GetNoOfMpdus () == 1 && !vhtSingleMpdu) + if (ampdu.GetRemainingNbOfMpdus () == 0 && !vhtSingleMpdu) { if (normalAck) { @@ -2869,24 +2850,16 @@ MacLow::DeaggregateAmpduAndReceive (Ptr 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 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 packet, const WifiMacHeader hdr) //Add packet tag AmpduTag ampdutag; ampdutag.SetAmpdu (true); - ampdutag.SetNoOfMpdus (1); - newPacket = currentAggregatedPacket; newPacket->AddHeader (peekedHdr); WifiMacTrailer fcs; diff --git a/src/wifi/model/mac-low.h b/src/wifi/model/mac-low.h index f487d0c15..105854687 100644 --- a/src/wifi/model/mac-low.h +++ b/src/wifi/model/mac-low.h @@ -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, double rxSnr, bool isEndOfFrame); + void ReceiveError (Ptr 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 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 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; //! packet, double snr, WifiTxVec } void -WifiPhyStateHelper::SwitchFromRxEndError (Ptr packet, double snr, bool isEndOfFrame) +WifiPhyStateHelper::SwitchFromRxEndError (Ptr packet, double snr) { m_rxErrorTrace (packet, snr); NotifyRxEndError (); DoSwitchFromRx (); if (!m_rxErrorCallback.IsNull ()) { - m_rxErrorCallback (packet, snr, isEndOfFrame); + m_rxErrorCallback (packet, snr); } } diff --git a/src/wifi/model/wifi-phy-state-helper.h b/src/wifi/model/wifi-phy-state-helper.h index da8301f26..35c3a7be8 100644 --- a/src/wifi/model/wifi-phy-state-helper.h +++ b/src/wifi/model/wifi-phy-state-helper.h @@ -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, double snr, bool isEndOfFrame); + void SwitchFromRxEndError (Ptr 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 packet, double snr, bool isEndOfFrame); + (Ptr packet, double snr); /** * TracedCallback signature for transmit event. diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index aa55f0e64..a23ff0599 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -192,9 +192,8 @@ public: /** * arg1: packet received unsuccessfully * arg2: snr of packet - * arg3: PHY-RXEND flag */ - typedef Callback, double, bool> RxErrorCallback; + typedef Callback, double> RxErrorCallback; static TypeId GetTypeId (void); diff --git a/src/wifi/model/yans-wifi-phy.cc b/src/wifi/model/yans-wifi-phy.cc index 2450bbe4f..815dbb3fc 100644 --- a/src/wifi/model/yans-wifi-phy.cc +++ b/src/wifi/model/yans-wifi-phy.cc @@ -655,16 +655,16 @@ YansWifiPhy::StartReceivePreambleAndHeader (Ptr 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, 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)