Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1432)

Unified Diff: src/wifi/model/mac-low.cc

Issue 14549044: Adding MPDU aggregation
Patch Set: changed A-MPDU implementation to simplify PCAP generation Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/wifi/model/mac-low.h ('k') | src/wifi/model/mac-tx-middle.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/wifi/model/mac-low.cc
===================================================================
--- a/src/wifi/model/mac-low.cc
+++ b/src/wifi/model/mac-low.cc
@@ -18,6 +18,7 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Mirko Banchi <mk.banchi@gmail.com>
+ * Author: Ghada Badawy <gbadawy@gmail.com>
*/
#include "ns3/assert.h"
@@ -34,6 +35,9 @@
#include "qos-utils.h"
#include "edca-txop-n.h"
#include "snr-tag.h"
+#include "yans-wifi-phy.h"
+#include "ampdu-tag.h"
+#include "wifi-mac-queue.h"
NS_LOG_COMPONENT_DEFINE ("MacLow");
@@ -51,7 +55,7 @@
}
void
MacLowTransmissionListener::GotBlockAck (const CtrlBAckResponseHeader *blockAck,
- Mac48Address source)
+ Mac48Address source, WifiMode mode)
{
}
void
@@ -72,6 +76,52 @@
{
}
+void MacLowBlockAckEventListener::SetAmpdu (bool ampdu)
+{
+}
+
+void MacLowBlockAckEventListener::CompleteTransfer(Mac48Address address, uint8_t tid)
+{
+}
+void
+MacLowBlockAckEventListener::CompleteMpduTx (Ptr<const Packet> packet, WifiMacHeader hdr, Time tstamp)
+{
+}
+
+uint16_t
+MacLowBlockAckEventListener::GetNextSequenceNumberfor (WifiMacHeader *hdr)
+{
+ return 0;
+}
+
+uint16_t
+MacLowBlockAckEventListener::PeekNextSequenceNumberfor (WifiMacHeader *hdr)
+{
+ return 0;
+}
+
+Ptr<const Packet>
+MacLowBlockAckEventListener::PeekNextPacketInBaQueue (WifiMacHeader &Hdr)
+{
+ return 0;
+}
+
+void
+MacLowBlockAckEventListener::RemoveFromBaQueue (Ptr<const Packet> packet)
+{
+}
+
+uint32_t
+MacLowBlockAckEventListener::GetNOutstandingPackets (Mac48Address recipient, uint8_t tid)
+{
+ return 0;
+}
+
+uint32_t
+MacLowBlockAckEventListener::GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const
+{
+ return 0;
+}
MacLowTransmissionParameters::MacLowTransmissionParameters ()
: m_nextSize (0),
m_waitAck (ACK_NONE),
@@ -261,10 +311,13 @@
virtual void NotifyRxStart (Time duration)
{
}
- virtual void NotifyRxEndOk (void)
+ virtual void NotifyRxEnd (void)
{
}
- virtual void NotifyRxEndError (void)
+ virtual void NotifyRxEndOk (void)
+ {
+ }
+ virtual void NotifyRxEndError (void)
{
}
virtual void NotifyTxStart (Time duration)
@@ -294,6 +347,8 @@
m_sendDataEvent (),
m_waitSifsEvent (),
m_endTxNoAckEvent (),
+ m_waitRifsEvent(),
+ m_mpduAggregator (0),
m_currentPacket (0),
m_listener (0)
{
@@ -301,6 +356,9 @@
m_lastNavDuration = Seconds (0);
m_lastNavStart = Seconds (0);
m_promisc = false;
+ m_sentMpdus=0;
+ m_aggregateQueue = CreateObject<WifiMacQueue> ();
+ m_random = CreateObject<UniformRandomVariable> ();
}
MacLow::~MacLow ()
@@ -314,7 +372,13 @@
m_phyMacLowListener = new PhyMacLowListener (this);
phy->RegisterListener (m_phyMacLowListener);
}
-
+int64_t
+MacLow::AssignStreams (int64_t stream)
+{
+ NS_LOG_FUNCTION (this << stream);
+ m_random->SetStream (stream);
+ return 1;
+}
void
MacLow::DoDispose (void)
@@ -336,6 +400,9 @@
m_stationManager = 0;
delete m_phyMacLowListener;
m_phyMacLowListener = 0;
+ m_mpduAggregator = 0;
+ m_sentMpdus = 0;
+ m_aggregateQueue = 0;
}
void
@@ -414,7 +481,7 @@
MacLow::SetPhy (Ptr<WifiPhy> phy)
{
m_phy = phy;
- m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::ReceiveOk, this));
+ m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::DeaggregateAmpduAndReceive, this));
m_phy->SetReceiveErrorCallback (MakeCallback (&MacLow::ReceiveError, this));
SetupPhyMacLowListener (phy);
}
@@ -551,7 +618,24 @@
m_dcfListeners.push_back (listener);
}
-
+bool
+MacLow::IsAmpdu(Ptr<const Packet> packet, const WifiMacHeader hdr)
+{
+ uint32_t size, actualSize;
+ WifiMacTrailer fcs;
+ Ptr<Packet> p;
+ p = packet->Copy();
+ size= packet->GetSize () + hdr.GetSize () + fcs.GetSerializedSize ();
+ p = AggregateToAmpdu (packet, hdr);
+ actualSize = p->GetSize();
+ if (actualSize > size)
+ {
+ m_currentPacket = p;
+ return true;
+ }
+ else
+ return false;
+}
void
MacLow::StartTransmission (Ptr<const Packet> packet,
const WifiMacHeader* hdr,
@@ -581,9 +665,15 @@
//NS_ASSERT (m_phy->IsStateIdle ());
- NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
+ m_ampdu=IsAmpdu(m_currentPacket,m_currentHdr);
+
+ NS_LOG_DEBUG ("startTx size=" << GetSize (m_currentPacket, m_currentHdr) <<
", to=" << m_currentHdr.GetAddr1 () << ", listener=" << m_listener);
+ if (m_ampdu)
+ m_txParams.EnableCompressedBlockAck ();
+
+
if (m_txParams.MustSendRts ())
{
SendRtsForPacket ();
@@ -640,7 +730,7 @@
}
void
-MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
+MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble, bool ampduSubframe)
{
NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble);
/* A packet is received from the PHY.
@@ -662,23 +752,30 @@
* idle. If the NAV at the STA receiving the RTS indicates the medium is not idle,
* that STA shall not respond to the RTS frame.
*/
- if (isPrevNavZero
- && hdr.GetAddr1 () == m_self)
+ if (ampduSubframe)
{
- NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
- NS_ASSERT (m_sendCtsEvent.IsExpired ());
- m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
- rxSnr, txMode);
- m_sendCtsEvent = Simulator::Schedule (GetSifs (),
- &MacLow::SendCtsAfterRts, this,
- hdr.GetAddr2 (),
- hdr.GetDuration (),
- txMode,
- rxSnr);
+ NS_FATAL_ERROR ("Received RTS as part of an A-MPDU");
}
else
{
- NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
+ if (isPrevNavZero
+ && hdr.GetAddr1 () == m_self)
+ {
+ NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
+ NS_ASSERT (m_sendCtsEvent.IsExpired ());
+ m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
+ rxSnr, txMode);
+ m_sendCtsEvent = Simulator::Schedule (GetSifs (),
+ &MacLow::SendCtsAfterRts, this,
+ hdr.GetAddr2 (),
+ hdr.GetDuration (),
+ txMode,
+ rxSnr);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
+ }
}
}
else if (hdr.IsCts ()
@@ -686,23 +783,30 @@
&& m_ctsTimeoutEvent.IsRunning ()
&& m_currentPacket != 0)
{
- NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
- SnrTag tag;
- packet->RemovePacketTag (tag);
- m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
- rxSnr, txMode);
- m_stationManager->ReportRtsOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
- rxSnr, txMode, tag.Get ());
+ if (ampduSubframe)
+ {
+ NS_FATAL_ERROR ("Received CTS as part of an A-MPDU");
+ }
+ else
+ {
+ NS_LOG_DEBUG ("receive cts from=" << m_currentHdr.GetAddr1 ());
+ SnrTag tag;
+ packet->RemovePacketTag (tag);
+ m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
+ rxSnr, txMode);
+ m_stationManager->ReportRtsOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
+ rxSnr, txMode, tag.Get ());
- m_ctsTimeoutEvent.Cancel ();
- NotifyCtsTimeoutResetNow ();
- m_listener->GotCts (rxSnr, txMode);
- NS_ASSERT (m_sendDataEvent.IsExpired ());
- m_sendDataEvent = Simulator::Schedule (GetSifs (),
- &MacLow::SendDataAfterCts, this,
- hdr.GetAddr1 (),
- hdr.GetDuration (),
- txMode);
+ m_ctsTimeoutEvent.Cancel ();
+ NotifyCtsTimeoutResetNow ();
+ m_listener->GotCts (rxSnr, txMode);
+ NS_ASSERT (m_sendDataEvent.IsExpired ());
+ m_sendDataEvent = Simulator::Schedule (GetSifs (),
+ &MacLow::SendDataAfterCts, this,
+ hdr.GetAddr1 (),
+ hdr.GetDuration (),
+ txMode);
+ }
}
else if (hdr.IsAck ()
&& hdr.GetAddr1 () == m_self
@@ -751,7 +855,9 @@
CtrlBAckResponseHeader blockAck;
packet->RemoveHeader (blockAck);
m_blockAckTimeoutEvent.Cancel ();
- m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ());
+ NotifyAckTimeoutResetNow ();
+ m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 (),txMode);
+ m_sentMpdus=0;
}
else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
{
@@ -805,14 +911,14 @@
m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
rxSnr, txMode);
- if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
+ if (hdr.IsQosData () && ReceiveMpdu (packet, hdr))
{
/* From section 9.10.4 in IEEE802.11:
Upon the receipt of a QoS data frame from the originator for which
the Block Ack agreement exists, the recipient shall buffer the MSDU
regardless of the value of the Ack Policy subfield within the
QoS Control field of the QoS data frame. */
- if (hdr.IsQosAck ())
+ if (hdr.IsQosAck () && !ampduSubframe)
{
AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (),
@@ -850,31 +956,52 @@
}
else if (hdr.IsQosData () && hdr.IsQosNoAck ())
{
- NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
+ if (ampduSubframe)
+ {
+ NS_LOG_DEBUG ("rx Ampdu with No Ack Policy from=" << hdr.GetAddr2 ());
+ }
+ else
+ {
+ NS_LOG_DEBUG ("rx unicast/noAck from=" << hdr.GetAddr2 ());
+ }
}
else if (hdr.IsData () || hdr.IsMgt ())
{
- NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
- NS_ASSERT (m_sendAckEvent.IsExpired ());
- m_sendAckEvent = Simulator::Schedule (GetSifs (),
- &MacLow::SendAckAfterData, this,
- hdr.GetAddr2 (),
- hdr.GetDuration (),
- txMode,
- rxSnr);
+ if (hdr.IsMgt() && ampduSubframe)
+ {
+ NS_FATAL_ERROR ("Received management packet as part of an A-MPDU");
+ }
+ else
+ {
+ NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
+ NS_ASSERT (m_sendAckEvent.IsExpired ());
+ m_sendAckEvent = Simulator::Schedule (GetSifs (),
+ &MacLow::SendAckAfterData, this,
+ hdr.GetAddr2 (),
+ hdr.GetDuration (),
+ txMode,
+ rxSnr);
+ }
}
goto rxPacket;
}
else if (hdr.GetAddr1 ().IsGroup ())
{
- if (hdr.IsData () || hdr.IsMgt ())
+ if (ampduSubframe)
{
- NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
- goto rxPacket;
+ NS_FATAL_ERROR ("Received group addressed packet as part of an A-MPDU");
}
else
{
- // DROP
+ if (hdr.IsData () || hdr.IsMgt ())
+ {
+ NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ());
+ goto rxPacket;
+ }
+ else
+ {
+ // DROP
+ }
}
}
else if (m_promisc)
@@ -897,6 +1024,27 @@
return;
}
+uint8_t
+MacLow::GetTid(Ptr<const Packet> packet, const WifiMacHeader hdr) const
+{
+ uint8_t tid;
+ if (hdr.IsQosData())
+ tid= hdr.GetQosTid ();
+ else if (hdr.IsBlockAckReq())
+ {
+ CtrlBAckRequestHeader baReqHdr;
+ packet->PeekHeader (baReqHdr);
+ tid=baReqHdr.GetTidInfo();
+ }
+ else if (hdr.IsBlockAck())
+ {
+ CtrlBAckResponseHeader baRespHdr;
+ packet->PeekHeader (baRespHdr);
+ tid=baRespHdr.GetTidInfo();
+ }
+ return tid;
+}
+
uint32_t
MacLow::GetAckSize (void) const
{
@@ -946,7 +1094,7 @@
preamble= WIFI_PREAMBLE_HT_MF;
else
preamble=WIFI_PREAMBLE_LONG;
- return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble);
+ return m_phy->CalculateTxDuration (GetAckSize (), ackTxVector, preamble,0,0);
}
Time
MacLow::GetBlockAckDuration (Mac48Address to, WifiTxVector blockAckReqTxVector, enum BlockAckType type) const
@@ -964,7 +1112,7 @@
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,0,0);
}
Time
MacLow::GetCtsDuration (Mac48Address to, WifiTxVector rtsTxVector) const
@@ -981,7 +1129,7 @@
preamble= WIFI_PREAMBLE_HT_MF;
else
preamble=WIFI_PREAMBLE_LONG;
- return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
+ return m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble,0,0);
}
uint32_t
MacLow::GetCtsSize (void) const
@@ -991,10 +1139,15 @@
return cts.GetSize () + 4;
}
uint32_t
-MacLow::GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
+MacLow::GetSize (Ptr<const Packet> packet, const WifiMacHeader hdr) const
{
+uint32_t size;
WifiMacTrailer fcs;
- return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
+ if (m_ampdu)
+ size = packet->GetSize ();
+ else
+ size= packet->GetSize () + hdr.GetSize () + fcs.GetSerializedSize ();
+ return size;
}
WifiTxVector
@@ -1064,7 +1217,7 @@
preamble=WIFI_PREAMBLE_LONG;
if (params.MustSendRts ())
{
- txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble);
+ txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, preamble,0,0);
txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector);
txTime += Time (GetSifs () * 2);
}
@@ -1075,8 +1228,8 @@
preamble= WIFI_PREAMBLE_HT_MF;
else
preamble=WIFI_PREAMBLE_LONG;
- uint32_t dataSize = GetSize (packet, hdr);
- txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble);
+ uint32_t dataSize = GetSize (packet, *hdr);
+ txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, preamble,0,0);
if (params.MustWaitAck ())
{
txTime += GetSifs ();
@@ -1103,7 +1256,7 @@
else
preamble=WIFI_PREAMBLE_LONG;
txTime += GetSifs ();
- txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble);
+ txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, preamble,0,0);
}
return txTime;
}
@@ -1141,7 +1294,7 @@
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,0,0) +
Time (2 * GetSifs ()) + Time (2 * GetSlotTime ());
m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
&MacLow::NavCounterResetCtsMissed, this,
@@ -1230,10 +1383,63 @@
", mode=" << txVector.GetMode() <<
", duration=" << hdr->GetDuration () <<
", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
- m_phy->SendPacket (packet, txVector.GetMode(), preamble, txVector);
+ if (!m_ampdu)
+ {
+ m_phy->SendPacket (packet, txVector.GetMode(), preamble, txVector,0);
+ }
+ else
+ {
+ Ptr<Packet> newPacket;
+ Ptr <const Packet> dequeuedPacket;
+ WifiMacHeader newHdr;
+ WifiMacTrailer fcs;
+ uint32_t queueSize = m_aggregateQueue->GetSize ();
+ bool last = false;
+ uint8_t packetType;
+ //Add packet tag
+ AmpduTag ampdutag;
+ ampdutag.SetAmpdu (true);
+ Time delay=Seconds(0);
+ for (;queueSize > 0; queueSize--)
+ {
+ dequeuedPacket = m_aggregateQueue->Dequeue(&newHdr);
+ newPacket = dequeuedPacket->Copy();
+ newHdr.SetDuration (hdr->GetDuration ());
+ newPacket->AddHeader (newHdr);
+ newPacket->AddTrailer (fcs);
+ if (queueSize==1)
+ {
+ last=true;
+ packetType=2;
+ }
+ m_mpduAggregator->AddHeaderAndPad (newPacket,last);
+
+ ampdutag.SetNoOfMpdus(queueSize);
+ newPacket->AddPacketTag(ampdutag);
+ if (delay ==Seconds(0))
+ {
+ NS_LOG_DEBUG("Sending MPDU as part of A-MPDU");
+ packetType=1;
+ m_phy->SendPacket (newPacket, txVector.GetMode(), preamble, txVector,packetType);
+
+ }
+ else
+ {
+ m_mpduTxEnd=Simulator::Schedule (delay, &MacLow::SendPacket, this,newPacket, txVector.GetMode(), preamble, txVector,packetType);
+ }
+ delay=delay+m_phy->CalculateTxDuration (GetSize (newPacket,newHdr), txVector, preamble,packetType,1);
+ preamble= WIFI_PREAMBLE_NONE;
+ }
+ }
}
void
+MacLow::SendPacket(Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, WifiTxVector txVector, uint8_t packetType)
+{
+ NS_LOG_DEBUG("Sending MPDU as part of A-MPDU");
+ m_phy->SendPacket (packet, txMode, preamble, txVector,packetType);
+}
+void
MacLow::CtsTimeout (void)
{
NS_LOG_FUNCTION (this);
@@ -1242,6 +1448,15 @@
/// we should restart a new cts timeout now until the expected
/// end of rx if there was a rx start before now.
m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+ uint32_t queueSize = m_aggregateQueue->GetSize ();
+ //since transmission will be retried clear mac-low
+ if (queueSize >= 1)
+ {
+ //remove any packets that we added to the aggregate queue
+ NS_LOG_DEBUG("Flush aggregate queue");
+ m_aggregateQueue->Flush();
+ }
+ m_sentMpdus = m_sentMpdus - queueSize;
m_currentPacket = 0;
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
@@ -1255,7 +1470,8 @@
/// \todo should check that there was no rx start before now.
/// we should restart a new ack timeout now until the expected
/// end of rx if there was a rx start before now.
- m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
+ if (m_currentHdr.IsData() || m_currentHdr.IsQosData()) //only report data failures because some nmanagement frames require an Ack as AddBa, AssocReq,...
+ m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
listener->MissedAck ();
@@ -1342,14 +1558,14 @@
duration += GetSifs ();
duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxVector);
duration += GetSifs ();
- duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
- dataTxVector, preamble);
+ duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, m_currentHdr),
+ dataTxVector, preamble,0,0);
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,0,0);
Time timerDelay = txDuration + GetCtsTimeout ();
NS_ASSERT (m_ctsTimeoutEvent.IsExpired ());
@@ -1377,7 +1593,7 @@
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,0,0);
if (m_txParams.MustWaitNormalAck ())
{
Time timerDelay = txDuration + GetAckTimeout ();
@@ -1478,7 +1694,7 @@
{
duration += GetSifs ();
duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
- dataTxVector, preamble);
+ dataTxVector, preamble,0,0);
if (m_txParams.MustWaitAck ())
{
duration += GetSifs ();
@@ -1488,9 +1704,13 @@
}
m_currentHdr.SetDuration (duration);
- m_currentPacket->AddHeader (m_currentHdr);
- WifiMacTrailer fcs;
- m_currentPacket->AddTrailer (fcs);
+ if (!m_ampdu)
+ {
+ m_currentPacket->AddHeader (m_currentHdr);
+ WifiMacTrailer fcs;
+ m_currentPacket->AddTrailer (fcs);
+ }
+
ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
m_currentPacket = 0;
@@ -1537,8 +1757,8 @@
{
WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
duration += GetSifs ();
- duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket,&m_currentHdr),
- dataTxVector, preamble);
+ duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket,m_currentHdr),
+ dataTxVector, preamble,0,0);
if (m_txParams.MustWaitBasicBlockAck ())
{
@@ -1559,7 +1779,7 @@
{
duration += GetSifs ();
duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
- dataTxVector, preamble);
+ dataTxVector, preamble,0,0);
if (m_txParams.MustWaitCompressedBlockAck ())
{
duration += GetSifs ();
@@ -1582,7 +1802,7 @@
ForwardDown (packet, &cts, ctsTxVector,preamble);
- Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble);
+ Time txDuration = m_phy->CalculateTxDuration (GetCtsSize (), ctsTxVector, preamble,0,0);
txDuration += GetSifs ();
NS_ASSERT (m_sendDataEvent.IsExpired ());
@@ -1650,10 +1870,41 @@
StartDataTxTimers (dataTxVector);
Time newDuration = Seconds (0);
- newDuration += GetSifs ();
- newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
- Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
- dataTxVector, preamble);
+
+ if (m_txParams.MustWaitBasicBlockAck ())
+ {
+ newDuration += GetSifs ();
+ newDuration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, BASIC_BLOCK_ACK);
+ }
+ else if (m_txParams.MustWaitCompressedBlockAck ())
+ {
+ newDuration += GetSifs ();
+ newDuration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
+ }
+ else if (m_txParams.MustWaitAck ())
+ {
+ newDuration += GetSifs ();
+ newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
+ }
+ if (m_txParams.HasNextPacket ())
+ {
+ newDuration += GetSifs ();
+ newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
+ dataTxVector, preamble,0,0);
+ if (m_txParams.MustWaitCompressedBlockAck ())
+ {
+ newDuration += GetSifs ();
+ newDuration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxVector, COMPRESSED_BLOCK_ACK);
+ }
+ else if (m_txParams.MustWaitAck ())
+ {
+ newDuration += GetSifs ();
+ newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxVector);
+ }
+ }
+
+ Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, m_currentHdr),
+ dataTxVector, preamble,0,0);
duration -= txDuration;
duration -= GetSifs ();
@@ -1661,9 +1912,13 @@
NS_ASSERT (duration >= MicroSeconds (0));
m_currentHdr.SetDuration (duration);
- m_currentPacket->AddHeader (m_currentHdr);
- WifiMacTrailer fcs;
- m_currentPacket->AddTrailer (fcs);
+ if (!m_ampdu)
+ {
+ m_currentPacket->AddHeader (m_currentHdr);
+ WifiMacTrailer fcs;
+ m_currentPacket->AddTrailer (fcs);
+ }
+
ForwardDown (m_currentPacket, &m_currentHdr, dataTxVector,preamble);
m_currentPacket = 0;
@@ -1732,6 +1987,49 @@
}
bool
+MacLow::IsInWindow (uint16_t seq, uint16_t winstart, uint16_t winsize)
+{
+ return ((seq - winstart+ 4096) % 4096) < winsize;
+}
+
+bool
+MacLow::ReceiveMpdu (Ptr<Packet> packet, WifiMacHeader hdr)
+{
+ if (m_stationManager->HasHtSupported())
+ {
+ Mac48Address originator =hdr.GetAddr2 ();
+ uint8_t tid = hdr.GetQosTid ();
+ uint16_t seqNumber = hdr.GetSequenceNumber ();
+ AgreementsI it = m_bAckAgreements.find (std::make_pair (originator,tid));
+ if (it != m_bAckAgreements.end ())
+ {
+ //Implement HT immediate Block Ack support for HT Delayed BlockAck is not added yet
+ if (!QosUtilsIsOldPacket ((*it).second.first.GetStartingSequence(), seqNumber))
+ {
+ StoreMpduIfNeeded(packet,hdr);
+ if (!IsInWindow(hdr.GetSequenceNumber (),(*it).second.first.GetStartingSequence(), (*it).second.first.GetBufferSize()))
+ {
+ uint16_t delta = (seqNumber - (*it).second.first.GetWinEnd()+ 4096) % 4096;
+ if (delta > 1)
+ {
+ (*it).second.first.SetWinEnd (seqNumber);
+ (*it).second.first.SetStartingSequence(((*it).second.first.GetWinEnd()-(*it).second.first.GetBufferSize() +1)%4096);
+ RxCompleteBufferedPacketsWithSmallerSequence ((*it).second.first.GetStartingSequence(), originator, tid);
+ }
+ }
+ RxCompleteBufferedPacketsUntilFirstLost (originator, tid);//forwards up packets starting from winstart and set winstart to last +1
+ (*it).second.first.SetWinEnd(((*it).second.first.GetStartingSequence()+(*it).second.first.GetBufferSize()-1)%4096);
+ }
+ return true;
+ }
+ return false;
+ }
+ else
+ return StoreMpduIfNeeded (packet,hdr);
+}
+
+
+bool
MacLow::StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr)
{
AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
@@ -1768,6 +2066,8 @@
{
uint8_t tid = respHdr->GetTid ();
BlockAckAgreement agreement (originator, tid);
+ //if the STA is an HT STA then the Immediate Block Ack is HT-Immediate BlockAck since
+ // no mixed networks is supported as off yet (i.e no backward compatibility)
if (respHdr->IsImmediateBlockAck ())
{
agreement.SetImmediateBlockAck ();
@@ -1780,6 +2080,7 @@
agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
agreement.SetTimeout (respHdr->GetTimeout ());
agreement.SetStartingSequence (startingSeq);
+ agreement.SetWinEnd ((agreement.GetStartingSequence()+ agreement.GetBufferSize()-1)%4096);
std::list<BufferedPacket> buffer (0);
AgreementKey key (originator, respHdr->GetTid ());
@@ -1841,9 +2142,11 @@
{
while (last != i)
{
+ NS_LOG_DEBUG ("forward up packet with seq " << (*i).second.GetSequenceNumber ());
m_rxCallback ((*last).first, &(*last).second);
last++;
}
+ NS_LOG_DEBUG ("forward up packet with seq " << (*i).second.GetSequenceNumber ());
m_rxCallback ((*last).first, &(*last).second);
last++;
/* go to next packet */
@@ -1897,9 +2200,11 @@
{
while (lastComplete != i)
{
+ NS_LOG_DEBUG ("forward up packet with seq " << (*i).second.GetSequenceNumber ());
m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
lastComplete++;
}
+ NS_LOG_DEBUG ("forward up packet with seq " << (*i).second.GetSequenceNumber ());
m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
lastComplete++;
}
@@ -1981,6 +2286,28 @@
ForwardDown (packet, &hdr, blockAckTxVector,preamble);
m_currentPacket = 0;
}
+void
+MacLow::SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator,
+ Time duration, WifiMode blockAckReqTxMode)
+{
+ NS_LOG_FUNCTION (this);
+ CtrlBAckResponseHeader blockAck;
+ uint16_t seqNumber;
+ BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
+ NS_ASSERT (i != m_bAckCaches.end ());
+ seqNumber = (*i).second.GetWinStart ();
+
+ bool immediate = true;
+ AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
+ blockAck.SetStartingSequence (seqNumber);
+ blockAck.SetTidInfo (tid);
+ immediate = (*it).second.first.IsImmediateBlockAck ();
+ blockAck.SetType (COMPRESSED_BLOCK_ACK);
+ NS_LOG_DEBUG ("Got Implicit block Ack Req with seq " << seqNumber);
+ (*i).second.FillBlockAckBitmap (&blockAck);
+
+ SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
+}
void
MacLow::SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Mac48Address originator,
@@ -2011,11 +2338,25 @@
NS_ASSERT (i != m_bAckCaches.end ());
(*i).second.FillBlockAckBitmap (&blockAck);
- /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
- * See 9.10.3 in IEEE8022.11e standard.
- */
- RxCompleteBufferedPacketsWithSmallerSequence (reqHdr.GetStartingSequence (), originator, tid);
- RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
+ if (!m_stationManager->HasHtSupported())
+ {
+ /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac
+ * See 9.10.3 in IEEE8022.11e standard.
+ */
+ RxCompleteBufferedPacketsWithSmallerSequence (reqHdr.GetStartingSequence (), originator, tid);
+ RxCompleteBufferedPacketsUntilFirstLost (originator, tid);
+ }
+ else
+ {
+ if (!QosUtilsIsOldPacket ((*it).second.first.GetStartingSequence(), reqHdr.GetStartingSequence ()))
+ {
+ (*it).second.first.SetStartingSequence(reqHdr.GetStartingSequence ());
+ (*it).second.first.SetWinEnd(((*it).second.first.GetStartingSequence()+(*it).second.first.GetBufferSize()-1)%4096);
+ RxCompleteBufferedPacketsWithSmallerSequence (reqHdr.GetStartingSequence (), originator, tid);
+ RxCompleteBufferedPacketsUntilFirstLost (originator, tid);//forwards up packets starting from winstart and set winstart to last +1
+ (*it).second.first.SetWinEnd(((*it).second.first.GetStartingSequence()+(*it).second.first.GetBufferSize()-1)%4096);
+ }
+ }
}
else
{
@@ -2040,9 +2381,7 @@
Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
- //std::map<AcIndex, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac);
- //NS_ASSERT (it != m_edcaListeners.end ());
-
+
agreement.m_inactivityEvent = Simulator::Schedule (timeout,
&MacLowBlockAckEventListener::BlockAckInactivityTimeout,
m_edcaListeners[ac],
@@ -2057,4 +2396,298 @@
m_edcaListeners.insert (std::make_pair (ac, listener));
}
+//mpdu aggregation happens here
+
+Ptr<MpduAggregator>
+MacLow::GetMpduAggregator (void) const
+{
+ return m_mpduAggregator;
+}
+
+
+void
+MacLow::SetMpduAggregator (Ptr<MpduAggregator> aggr)
+{
+ m_mpduAggregator = aggr;
+}
+
+
+void
+MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr, WifiMode txMode, WifiPreamble preamble)
+{
+ AmpduTag ampdu;
+ bool normalAck=false;
+ bool ampduSubframe=false;
+ uint16_t startingSeqNumber=5000;
+ if (aggregatedPacket->RemovePacketTag(ampdu))
+ {
+ ampduSubframe=true;
+ MpduAggregator::DeaggregatedMpdus packets = MpduAggregator::Deaggregate (aggregatedPacket);
+ MpduAggregator::DeaggregatedMpdusCI n = packets.begin ();
+
+ WifiMacHeader firsthdr;
+ (*n).first->PeekHeader(firsthdr);
+ NS_LOG_DEBUG ("duration/id=" << firsthdr.GetDuration ());
+ NotifyNav ((*n).first,firsthdr, txMode, preamble);
+ if (firsthdr.GetAddr1 () == m_self)
+ {
+ if (firsthdr.IsAck() || firsthdr.IsBlockAck() || firsthdr.IsBlockAckReq())
+ {
+ ReceiveOk ((*n).first,rxSnr, txMode, preamble, ampduSubframe);
+ }
+ else if (firsthdr.IsData () || firsthdr.IsQosData())
+ {
+ startingSeqNumber=firsthdr.GetSequenceNumber();
+ NS_LOG_DEBUG ("Deaagregate packet with sequence=" << startingSeqNumber);
+ ReceiveOk ((*n).first,rxSnr, txMode, preamble, ampduSubframe);
+ if (firsthdr.IsQosAck())
+ {
+ NS_LOG_DEBUG ("Normal Ack");
+ normalAck=true;
+ }
+ }
+ else
+ NS_FATAL_ERROR ("Received A-MPDU with invalid MPDU type");
+ }
+
+ if (normalAck && ampdu.GetNoOfMpdus() ==1)
+ {
+ //send block Ack
+ if (firsthdr.IsBlockAckReq())
+ {
+ NS_FATAL_ERROR ("Sending a BlockAckReq with QosPolicy equal to Normal Ack");
+ }
+ uint8_t tid = firsthdr.GetQosTid ();
+ 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 IEEE802.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 (),
+ txMode);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("There's not a valid agreement for this block ack request.");
+ }
+ }// normal Ack
+ }// !self
+ else
+ {
+
+ ReceiveOk (aggregatedPacket,rxSnr, txMode, preamble, ampduSubframe);
+
+ }
+}
+
+bool
+MacLow::StopAggregation(Ptr<const Packet> peekedPacket, WifiMacHeader peekedHdr, Ptr<Packet> aggregatedPacket, uint16_t size) const
+{
+ if (peekedPacket == 0)
+ return true;
+ if (!m_mpduAggregator->CanBeAggregated (peekedPacket->GetSize()+peekedHdr.GetSize()+WIFI_MAC_FCS_LENGTH, aggregatedPacket, size))
+ return true;
+ //since m_sendMpdus is not reset except when we get an ack or blockack this line doesn't allow more than x MPDUs to be transmitted
+ if ((m_sentMpdus*(peekedPacket->GetSize()+peekedHdr.GetSize()+WIFI_MAC_FCS_LENGTH +6)) + size >= m_mpduAggregator->GetAmpduSize())
+ return true;
+ return false;
+}
+
+
+Ptr<Packet>
+MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr)
+{
+ bool isAmpdu=false;
+ Ptr<Packet> newPacket;
+ WifiMacHeader peekedHdr;
+ newPacket=packet->Copy();
+ peekedHdr=hdr;
+ //missing hdr.IsAck() sincewe have no means of knowing the Tid of the Ack yet
+ if (hdr.IsQosData()|| hdr.IsBlockAck()|| hdr.IsBlockAckReq())
+ {
+
+ Time tstamp;
+ uint8_t tid;
+ tid=GetTid(packet,hdr);
+ Ptr<WifiMacQueue> queue;
+ AcIndex ac = QosUtilsMapTidToAc (tid);
+ //since a blockack agreement always preceeds mpdu aggregation there should alway exist blockAck listener
+ std::map<AcIndex, MacLowBlockAckEventListener*>::const_iterator listenerIt = m_edcaListeners.find(ac);
+ NS_ASSERT (listenerIt != m_edcaListeners.end ());
+ queue = listenerIt->second->GetQueue();
+
+ if (!hdr.GetAddr1 ().IsBroadcast () && m_mpduAggregator!= 0)
+ {
+ //Have to make sure that their exist a block Ack agreement before sending an AMPDU (BlockAck Manager)
+ if (listenerIt->second->GetBlockAckAgreementExists (hdr.GetAddr1(), tid))
+ {
+
+ /* here is performed mpdu aggregation */
+ /* MSDU aggregation happened in edca if the user asked for it so m_cuurentPacket may contains a normal packet or a A-MSDU*/
+ Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
+ peekedHdr=hdr;
+ //get new ampdu duration
+ Time duration = peekedHdr.GetDuration();
+ uint16_t startingSequenceNumber=0; //max sequence number id 4095 and it repeats, makes sure number of unacknowledged is < 64
+ uint16_t currentSequenceNumber=0;
+ uint8_t qosPolicy=0;
+ uint16_t blockAckSize=0;
+ bool aggregated = false;
+ int i=0;
+ Ptr<Packet> aggPacket= newPacket->Copy();
+
+ if (!hdr.IsBlockAckReq())
+ {
+ if (!hdr.IsBlockAck())
+ {
+ startingSequenceNumber=peekedHdr.GetSequenceNumber();
+ peekedHdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+ }
+ newPacket->AddHeader (peekedHdr);
+ WifiMacTrailer fcs;
+ newPacket->AddTrailer (fcs);
+
+ aggregated=m_mpduAggregator->Aggregate (newPacket, currentAggregatedPacket);
+ if (aggregated)
+ {
+ NS_LOG_DEBUG ("Adding packet with Sequnce number " << peekedHdr.GetSequenceNumber()<<" to A-MPDU");
+ i++;
+ m_sentMpdus++;
+ m_aggregateQueue->Enqueue (aggPacket,peekedHdr);
+ }
+ }
+ else if (hdr.IsBlockAckReq())
+ {
+ blockAckSize=packet->GetSize()+hdr.GetSize()+WIFI_MAC_FCS_LENGTH;
+ qosPolicy=3; //if the last subrame is block ack req then set ack policy of all frames to blockack
+ CtrlBAckRequestHeader blockAckReq;
+ packet->PeekHeader (blockAckReq);
+ startingSequenceNumber = blockAckReq.GetStartingSequence ();
+ }
+ aggregated = false;
+ bool retry = false;
+ //looks for other packets to the same destination with the same Tid need to extend that to include MSDUs
+ Ptr<const Packet> peekedPacket= listenerIt->second->PeekNextPacketInBaQueue(peekedHdr);
+ if (peekedPacket==0)
+ {
+ peekedPacket = queue->PeekByTidAndAddress (&peekedHdr, tid,
+ WifiMacHeader::ADDR1,
+ hdr.GetAddr1 (),&tstamp);
+ currentSequenceNumber = listenerIt->second->PeekNextSequenceNumberfor (&peekedHdr);
+ }
+ else
+ {
+ retry = true;
+ currentSequenceNumber = peekedHdr.GetSequenceNumber();
+ }
+ while (currentSequenceNumber < (startingSequenceNumber + 63) && listenerIt->second->GetNOutstandingPackets(hdr.GetAddr1(), tid) < 63 &&!StopAggregation (peekedPacket,peekedHdr,currentAggregatedPacket, blockAckSize))
+ {
+ //for now always send AMPDU with normal ACK
+ if (retry==false)
+ {
+ currentSequenceNumber = listenerIt->second->GetNextSequenceNumberfor (&peekedHdr);
+ peekedHdr.SetSequenceNumber (currentSequenceNumber);
+ peekedHdr.SetFragmentNumber (0);
+ peekedHdr.SetNoMoreFragments ();
+ peekedHdr.SetNoRetry ();
+ }
+ if (qosPolicy==0)
+ peekedHdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+ else
+ peekedHdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK);
+ newPacket=peekedPacket->Copy();
+ Ptr<Packet> aggPacket= newPacket->Copy();
+
+ newPacket->AddHeader (peekedHdr);
+ WifiMacTrailer fcs;
+ newPacket->AddTrailer (fcs);
+ aggregated=m_mpduAggregator->Aggregate (newPacket, currentAggregatedPacket);
+ if (aggregated)
+ {
+ m_aggregateQueue->Enqueue (aggPacket,peekedHdr);
+ if (i==1 && hdr.IsQosData())
+ listenerIt->second->CompleteMpduTx(packet,hdr,tstamp);
+ NS_LOG_DEBUG ("Adding packet with Sequnce number " << peekedHdr.GetSequenceNumber()<<" to A-MPDU");
+ i++;
+ isAmpdu=true;
+ m_sentMpdus++;
+ listenerIt->second->CompleteMpduTx(peekedPacket,peekedHdr,tstamp);
+ if (retry)
+ listenerIt->second->RemoveFromBaQueue(peekedPacket);
+ else
+ queue->Remove (peekedPacket);
+ newPacket=0;
+ }//aggregated
+ else
+ break;
+ if (retry==true)
+ {
+ peekedPacket= listenerIt->second->PeekNextPacketInBaQueue(peekedHdr);
+
+ if (peekedPacket == 0)
+ {
+ //I reached the first packet that I added to this A-MPDU
+ retry=false;
+ peekedPacket = queue->PeekByTidAndAddress (&peekedHdr, tid,
+ WifiMacHeader::ADDR1, hdr.GetAddr1 (), &tstamp);
+ }
+ else
+ currentSequenceNumber = peekedHdr.GetSequenceNumber();
+ }
+ else
+ {
+ peekedPacket = queue->PeekByTidAndAddress (&peekedHdr, tid,
+ WifiMacHeader::ADDR1, hdr.GetAddr1 (), &tstamp);
+ }
+
+ }//while
+ if (isAmpdu)
+ {
+ if (hdr.IsBlockAckReq())
+ {
+ newPacket=packet->Copy();
+ peekedHdr=hdr;
+ Ptr<Packet> aggPacket= newPacket->Copy();
+ m_aggregateQueue->Enqueue (aggPacket,peekedHdr);
+ newPacket->AddHeader (peekedHdr);
+ WifiMacTrailer fcs;
+ newPacket->AddTrailer (fcs);
+ m_mpduAggregator->Aggregate (newPacket, currentAggregatedPacket);
+ }
+ if (qosPolicy==0)
+ {
+ listenerIt->second->CompleteTransfer(hdr.GetAddr1 (),tid);
+ }
+ //Add packet tag
+ AmpduTag ampdutag;
+ ampdutag.SetAmpdu (true);
+ ampdutag.SetNoOfMpdus(i);
+ newPacket = currentAggregatedPacket;
+ newPacket->AddPacketTag(ampdutag);
+ currentAggregatedPacket = 0;
+ NS_LOG_DEBUG ("tx unicast A-MPDU");
+ listenerIt->second->SetAmpdu(true);
+ }
+ else
+ {
+ uint32_t queueSize = m_aggregateQueue->GetSize ();
+ NS_ASSERT (queueSize <= 2); //since it is not an A-MPDU then only 2 packets should have been added to the queue no more
+ if (queueSize >= 1)
+ {
+ //remove any packets that we added to the aggregate queue
+ NS_LOG_DEBUG("Flush aggregate queue");
+ m_aggregateQueue->Flush();
+ }
+ }
+ }//if block ack
+ }//if aggregate
+ }//if appropoaite header
+ return newPacket;
+}
} // namespace ns3
« no previous file with comments | « src/wifi/model/mac-low.h ('k') | src/wifi/model/mac-tx-middle.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b