wifi: Make QosTxop independent of MacLow

This commit is contained in:
Stefano Avallone
2020-12-03 09:56:32 +01:00
parent 12745641e6
commit 2ea96f9f18
4 changed files with 21 additions and 580 deletions

View File

@@ -485,14 +485,13 @@ MacLow::StartTransmission (Ptr<WifiMacQueueItem> mpdu,
}
// QosTxop may send us a peeked frame
Ptr<const WifiMacQueueItem> tmp = qosTxop->PeekNextFrame ();
Ptr<const WifiMacQueueItem> tmp;
bool isPeeked = (tmp != 0 && tmp->GetPacket () == mpdu->GetPacket ());
Ptr<WifiMacQueueItem> newMpdu;
// If the frame has been peeked, dequeue it if it meets the size and duration constraints
if (isPeeked)
{
newMpdu = qosTxop->DequeuePeekedFrame (mpdu, m_currentTxVector, true, 0, txopLimit);
}
else if (IsWithinSizeAndTimeLimits (mpdu, m_currentTxVector, 0, txopLimit))
{
@@ -1009,8 +1008,6 @@ MacLow::ReceiveOk (Ptr<WifiMacQueueItem> mpdu, double rxSnr, WifiTxVector txVect
data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard
them and shall send a DELBA frame using the normal access
mechanisms. */
AcIndex ac = QosUtilsMapTidToAc (hdr.GetQosTid ());
m_edca[ac]->SendDelbaFrame (hdr.GetAddr2 (), hdr.GetQosTid (), false);
return;
}
else if (hdr.IsQosData () && hdr.IsQosNoAck ())
@@ -1968,14 +1965,6 @@ MacLow::CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Add
if (respHdr->GetTimeout () != 0)
{
AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
it->second.first.m_inactivityEvent = Simulator::Schedule (timeout,
&QosTxop::SendDelbaFrame,
m_edca[ac], originator, tid, false);
}
}
@@ -2230,12 +2219,6 @@ MacLow::ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement)
{
NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
agreement.m_inactivityEvent.Cancel ();
Time timeout = MicroSeconds (1024 * agreement.GetTimeout ());
AcIndex ac = QosUtilsMapTidToAc (agreement.GetTid ());
agreement.m_inactivityEvent = Simulator::Schedule (timeout,
&QosTxop::SendDelbaFrame,
m_edca[ac], agreement.GetPeer (),
agreement.GetTid (), false);
}
}

View File

@@ -31,7 +31,6 @@
#include "mgt-headers.h"
#include "wifi-mac-trailer.h"
#include "wifi-mac-queue.h"
#include "mac-low.h"
#include "qos-blocked-destinations.h"
#include "wifi-remote-station-manager.h"
#include "msdu-aggregator.h"
@@ -43,7 +42,7 @@
#include "wifi-tx-parameters.h"
#undef NS_LOG_APPEND_CONTEXT
#define NS_LOG_APPEND_CONTEXT if (m_low != 0) { std::clog << "[mac=" << m_low->GetAddress () << "] "; }
#define NS_LOG_APPEND_CONTEXT if (m_stationManager != 0 && m_stationManager->GetMac () != 0) { std::clog << "[mac=" << m_stationManager->GetMac ()->GetAddress () << "] "; }
namespace ns3 {
@@ -176,15 +175,16 @@ Ptr<const WifiMacQueueItem>
QosTxop::PrepareBlockAckRequest (Mac48Address recipient, uint8_t tid) const
{
NS_LOG_FUNCTION (this << recipient << +tid);
NS_ASSERT (QosUtilsMapTidToAc (tid) == m_ac);
CtrlBAckRequestHeader reqHdr = m_low->GetEdca (tid)->m_baManager->GetBlockAckReqHeader (recipient, tid);
CtrlBAckRequestHeader reqHdr = m_baManager->GetBlockAckReqHeader (recipient, tid);
Ptr<Packet> bar = Create<Packet> ();
bar->AddHeader (reqHdr);
WifiMacHeader hdr;
hdr.SetType (WIFI_MAC_CTL_BACKREQ);
hdr.SetAddr1 (recipient);
hdr.SetAddr2 (m_low->GetAddress ());
hdr.SetAddr2 (m_stationManager->GetMac ()->GetAddress ());
hdr.SetDsNotTo ();
hdr.SetDsNotFrom ();
hdr.SetNoRetry ();
@@ -272,166 +272,6 @@ QosTxop::IsQosOldPacket (Ptr<const WifiMacQueueItem> mpdu)
return false;
}
Ptr<const WifiMacQueueItem>
QosTxop::PeekNextFrame (uint8_t tid, Mac48Address recipient)
{
NS_LOG_FUNCTION (this);
WifiMacQueue::ConstIterator it = WifiMacQueue::EMPTY;
// lambda to peek the next frame
auto peek = [this, &tid, &recipient, &it] (Ptr<WifiMacQueue> queue)
{
if (tid == 8 && recipient.IsGroup ()) // undefined TID and recipient
{
return queue->PeekFirstAvailable (m_qosBlockedDestinations, it);
}
return queue->PeekByTidAndAddress (tid, recipient, it);
};
// check if there is a packet in the BlockAckManager retransmit queue
it = peek (m_baManager->GetRetransmitQueue ());
// remove old packets
while (it != m_baManager->GetRetransmitQueue ()->end () && IsQosOldPacket (*it))
{
NS_LOG_DEBUG ("removing an old packet from BlockAckManager retransmit queue: " << **it);
it = m_baManager->GetRetransmitQueue ()->Remove (it);
it = peek (m_baManager->GetRetransmitQueue ());
}
if (it != m_baManager->GetRetransmitQueue ()->end ())
{
NS_LOG_DEBUG ("packet peeked from BlockAckManager retransmit queue: " << **it);
return *it;
}
// otherwise, check if there is a packet in the EDCA queue
it = WifiMacQueue::EMPTY;
it = peek (m_queue);
if (it != m_queue->end ())
{
// peek the next sequence number and check if it is within the transmit window
// in case of QoS data frame
uint16_t sequence = m_txMiddle->PeekNextSequenceNumberFor (&(*it)->GetHeader ());
if ((*it)->GetHeader ().IsQosData ())
{
Mac48Address recipient = (*it)->GetHeader ().GetAddr1 ();
uint8_t tid = (*it)->GetHeader ().GetQosTid ();
if (GetBaAgreementEstablished (recipient, tid)
&& !IsInWindow (sequence, GetBaStartingSequence (recipient, tid), GetBaBufferSize (recipient, tid)))
{
NS_LOG_DEBUG ("packet beyond the end of the current transmit window");
return 0;
}
}
WifiMacHeader hdr = (*it)->GetHeader ();
hdr.SetSequenceNumber (sequence);
hdr.SetFragmentNumber (0);
hdr.SetNoMoreFragments ();
hdr.SetNoRetry ();
Ptr<const WifiMacQueueItem> item = Create<const WifiMacQueueItem> ((*it)->GetPacket (), hdr, (*it)->GetTimeStamp ());
NS_LOG_DEBUG ("packet peeked from EDCA queue: " << *item);
return item;
}
return 0;
}
Ptr<WifiMacQueueItem>
QosTxop::DequeuePeekedFrame (Ptr<const WifiMacQueueItem> peekedItem, WifiTxVector txVector,
bool aggregate, uint32_t ampduSize, Time ppduDurationLimit)
{
NS_LOG_FUNCTION (this << peekedItem << txVector << ampduSize << ppduDurationLimit);
NS_ASSERT (peekedItem != 0);
// do not dequeue the frame if it is a QoS data frame that does not meet the
// max A-MPDU size limit (if applicable) or the duration limit (if applicable)
if (peekedItem->GetHeader ().IsQosData () &&
!m_low->IsWithinSizeAndTimeLimits (peekedItem, txVector, ampduSize, ppduDurationLimit))
{
return 0;
}
Mac48Address recipient = peekedItem->GetHeader ().GetAddr1 ();
Ptr<WifiMacQueueItem> item;
Ptr<const WifiMacQueueItem> testItem;
WifiMacQueue::ConstIterator testIt;
// the packet can only have been peeked from the block ack manager retransmit
// queue if:
// - the peeked packet is a QoS Data frame AND
// - the peeked packet is not a group addressed frame AND
// - an agreement has been established
if (peekedItem->GetHeader ().IsQosData () && !recipient.IsGroup ()
&& GetBaAgreementEstablished (recipient, peekedItem->GetHeader ().GetQosTid ()))
{
uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
testIt = m_baManager->GetRetransmitQueue ()->PeekByTidAndAddress (tid, recipient);
if (testIt != m_baManager->GetRetransmitQueue ()->end ())
{
testItem = *testIt;
// if not null, the test packet must equal the peeked packet
NS_ASSERT (testItem->GetPacket () == peekedItem->GetPacket ());
// we should not be asked to dequeue an old packet
NS_ASSERT (!QosUtilsIsOldPacket (GetBaStartingSequence (recipient, tid),
testItem->GetHeader ().GetSequenceNumber ()));
item = m_baManager->GetRetransmitQueue ()->Dequeue (testIt);
NS_LOG_DEBUG ("dequeued from BA manager queue: " << *item);
return item;
}
}
// The packet has been peeked from the EDCA queue.
// If it is a QoS Data frame and it is not a broadcast frame, attempt A-MSDU
// aggregation if aggregate is true
if (peekedItem->GetHeader ().IsQosData ())
{
uint8_t tid = peekedItem->GetHeader ().GetQosTid ();
testIt = m_queue->PeekByTidAndAddress (tid, recipient);
NS_ASSERT (testIt != m_queue->end () && (*testIt)->GetPacket () == peekedItem->GetPacket ());
uint16_t sequence = m_txMiddle->PeekNextSequenceNumberFor (&peekedItem->GetHeader ());
// check if the peeked packet is within the transmit window
if (GetBaAgreementEstablished (recipient, tid)
&& !IsInWindow (sequence, GetBaStartingSequence (recipient, tid), GetBaBufferSize (recipient, tid)))
{
NS_LOG_DEBUG ("packet beyond the end of the current transmit window");
return 0;
}
if (item != 0)
{
NS_LOG_DEBUG ("tx unicast A-MSDU");
}
else // aggregation was not attempted or failed
{
item = m_queue->Dequeue (testIt);
}
}
else
{
// the peeked packet is a non-QoS Data frame (e.g., a DELBA Request), hence
// it was not peeked by TID, hence it must be the head of the queue
item = m_queue->DequeueFirstAvailable (m_qosBlockedDestinations);
NS_ASSERT (item != 0 && item->GetPacket () == peekedItem->GetPacket ());
}
NS_ASSERT (item != 0);
// Assign a sequence number to the MSDU or A-MSDU dequeued from the EDCA queue
uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&item->GetHeader ());
item->GetHeader ().SetSequenceNumber (sequence);
item->GetHeader ().SetFragmentNumber (0);
item->GetHeader ().SetNoMoreFragments ();
item->GetHeader ().SetNoRetry ();
NS_LOG_DEBUG ("dequeued from EDCA queue: " << *item);
return item;
}
Ptr<const WifiMacQueueItem>
QosTxop::PeekNextMpdu (uint8_t tid, Mac48Address recipient)
{
@@ -653,8 +493,7 @@ QosTxop::GetTransmissionParameters (Ptr<const WifiMacQueueItem> frame) const
// Enable/disable RTS
if (!frame->GetHeader ().IsBlockAckReq ()
&& m_stationManager->NeedRts (frame->GetHeader (), frame->GetSize ())
&& !m_low->IsCfPeriod ())
&& m_stationManager->NeedRts (frame->GetHeader (), frame->GetSize ()))
{
params.EnableRts ();
}
@@ -702,136 +541,7 @@ QosTxop::UpdateCurrentPacket (Ptr<WifiMacQueueItem> mpdu)
}
void
QosTxop::NotifyAccessGranted (void)
{
NS_LOG_FUNCTION (this);
// TODO FEM may have changed m_access to GRANTED, so the assert below holds not
// always true. Anyway, this function will soon be removed altogether.
// NS_ASSERT (m_access == REQUESTED);
m_access = NOT_REQUESTED;
m_isAccessRequestedForRts = false;
m_startTxop = Simulator::Now ();
// discard the current packet if it is a QoS Data frame with expired lifetime
if (m_currentPacket != 0 && m_currentHdr.IsQosData ()
&& (m_currentPacketTimestamp + m_queue->GetMaxDelay () < Simulator::Now ()))
{
NS_LOG_DEBUG ("the lifetime of current packet expired");
m_currentPacket = 0;
}
// If the current packet is a QoS Data frame, then there must be no block ack agreement
// established with the receiver for the TID of the packet. Indeed, retransmission
// of MPDUs sent under a block ack agreement is handled through the retransmit queue.
NS_ASSERT (m_currentPacket == 0 || !m_currentHdr.IsQosData ()
|| !GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()));
if (m_currentPacket == 0)
{
Ptr<const WifiMacQueueItem> peekedItem = m_baManager->GetBar ();
if (peekedItem != 0)
{
m_currentHdr = peekedItem->GetHeader ();
m_currentPacket = peekedItem->GetPacket ();
m_currentPacketTimestamp = Simulator::Now ();
}
else
{
peekedItem = PeekNextFrame ();
if (peekedItem == 0)
{
NS_LOG_DEBUG ("no packets available for transmission");
return;
}
// check if a block ack agreement needs to be established
m_currentHdr = peekedItem->GetHeader ();
m_currentPacket = peekedItem->GetPacket ();
if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsGroup ()
&& m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ())
&& (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())
|| m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET))
&& SetupBlockAckIfNeeded ())
{
return;
}
Ptr<WifiMacQueueItem> item;
// non-group addressed QoS Data frames may be sent in MU PPDUs. Given that at this stage
// we do not know the bandwidth it would be given nor the selected acknowledgment
// sequence, we cannot determine the constraints on size and duration limit. Hence,
// we only peek the non-group addressed QoS Data frame. MacLow will be in charge of
// computing the correct limits and dequeue the frame.
if (peekedItem->GetHeader ().IsQosData () && !peekedItem->GetHeader ().GetAddr1 ().IsGroup ()
&& !NeedFragmentation ())
{
item = Copy (peekedItem);
}
else
{
// compute the limit on the PPDU duration due to the TXOP duration, if any
Time ppduDurationLimit = Time::Min ();
if (peekedItem->GetHeader ().IsQosData () && GetTxopLimit ().IsStrictlyPositive ())
{
MacLowTransmissionParameters params = GetTransmissionParameters (peekedItem);
ppduDurationLimit = GetTxopRemaining () - m_low->CalculateOverheadTxTime (peekedItem, params);
}
// dequeue the peeked item if it fits within the TXOP duration, if any
item = DequeuePeekedFrame (peekedItem, m_low->GetDataTxVector (peekedItem),
!NeedFragmentation (), 0, ppduDurationLimit);
}
if (item == 0)
{
NS_LOG_DEBUG ("Not enough time in the current TXOP");
return;
}
m_currentPacket = item->GetPacket ();
m_currentHdr = item->GetHeader ();
m_currentPacketTimestamp = item->GetTimeStamp ();
m_fragmentNumber = 0;
}
NS_ASSERT (m_currentPacket != 0);
}
Ptr<WifiMacQueueItem> mpdu = Create <WifiMacQueueItem> (m_currentPacket, m_currentHdr,
m_currentPacketTimestamp);
m_currentParams = GetTransmissionParameters (mpdu);
if (m_currentHdr.GetAddr1 ().IsGroup ())
{
NS_LOG_DEBUG ("tx broadcast");
m_low->StartTransmission (mpdu, m_currentParams, this);
}
//With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
else if (((m_currentHdr.IsQosData () && !m_currentHdr.IsQosAmsdu ())
|| (m_currentHdr.IsData () && !m_currentHdr.IsQosData ()))
&& (GetBlockAckThreshold () == 0 || m_blockAckType.m_variant == BlockAckType::BASIC)
&& NeedFragmentation ())
{
m_currentIsFragmented = true;
m_currentParams.DisableRts ();
WifiMacHeader hdr;
Ptr<Packet> fragment = GetFragmentPacket (&hdr);
if (IsLastFragment ())
{
NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
m_currentParams.DisableNextData ();
}
else
{
NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
m_currentParams.EnableNextData (GetNextFragmentSize ());
}
m_low->StartTransmission (Create<WifiMacQueueItem> (fragment, hdr),
m_currentParams, this);
}
else
{
m_currentIsFragmented = false;
m_low->StartTransmission (mpdu, m_currentParams, this);
}
}
void QosTxop::NotifyInternalCollision (void)
QosTxop::NotifyInternalCollision (void)
{
NS_LOG_FUNCTION (this);
@@ -985,10 +695,6 @@ QosTxop::GotAck (void)
{
m_baManager->DestroyAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
}
else
{
m_low->DestroyBlockAckAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
}
}
else if (actionHdr.GetAction ().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
{
@@ -1273,77 +979,6 @@ QosTxop::NeedBarRetransmission (void)
return m_baManager->NeedBarRetransmission (tid, m_currentHdr.GetAddr1 ());
}
void
QosTxop::StartNextPacket (void)
{
NS_LOG_FUNCTION (this);
NS_ASSERT (GetTxopLimit ().IsStrictlyPositive () && GetTxopRemaining ().IsStrictlyPositive ());
m_currentPacket = 0;
// peek the next BlockAckReq, if any
Ptr<const WifiMacQueueItem> nextFrame = m_baManager->GetBar (false);
if (nextFrame == 0)
{
nextFrame = PeekNextFrame ();
}
if (nextFrame != 0)
{
MacLowTransmissionParameters params = GetTransmissionParameters (nextFrame);
if (GetTxopRemaining () >= m_low->CalculateOverallTxTime (nextFrame->GetPacket (), &nextFrame->GetHeader (), params))
{
// check if a block ack agreement needs to be established
m_currentHdr = nextFrame->GetHeader ();
m_currentPacket = nextFrame->GetPacket ();
if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsGroup ()
&& m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ())
&& (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())
|| m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET))
&& SetupBlockAckIfNeeded ())
{
return;
}
Ptr<WifiMacQueueItem> item;
if (nextFrame->GetHeader ().IsBlockAckReq ())
{
item = Copy (m_baManager->GetBar ());
}
// non-group addressed QoS Data frames may be sent in MU PPDUs. Given that at this stage
// we do not know the bandwidth it would be given nor the selected acknowledgment
// sequence, we cannot determine the constraints on size and duration limit. Hence,
// we only peek the non-group addressed QoS Data frame. MacLow will be in charge of
// computing the correct limits and dequeue the frame.
else if (nextFrame->GetHeader ().IsQosData () && !nextFrame->GetHeader ().GetAddr1 ().IsGroup ())
{
item = Copy (nextFrame);
}
else
{
// dequeue the peeked frame
item = DequeuePeekedFrame (nextFrame, m_low->GetDataTxVector (nextFrame));
}
NS_ASSERT (item != 0);
NS_LOG_DEBUG ("start next packet " << *item << " within the current TXOP");
m_currentPacket = item->GetPacket ();
m_currentHdr = item->GetHeader ();
m_currentPacketTimestamp = item->GetTimeStamp ();
NS_ASSERT (m_currentPacket != 0);
m_currentParams = params;
m_fragmentNumber = 0;
GetLow ()->StartTransmission (item, m_currentParams, this);
return;
}
}
// terminate TXOP because no (suitable) frame was found
TerminateTxop ();
}
void
QosTxop::TerminateTxop (void)
{
@@ -1435,10 +1070,7 @@ QosTxop::NeedFragmentation (void) const
|| GetAmpduExist (m_currentHdr.GetAddr1 ())
|| (m_stationManager->GetHtSupported ()
&& m_currentHdr.IsQosData ()
&& GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr))
&& GetLow ()->GetMpduAggregator () != 0 && m_stationManager->GetHtSupported (m_currentHdr.GetAddr1 ())
&& GetLow ()->GetMpduAggregator ()->GetMaxAmpduSize (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr),
WIFI_MOD_CLASS_HT) >= m_currentPacket->GetSize ()))
&& GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr))))
{
//MSDU is not fragmented when it is transmitted using an HT-immediate or
//HT-delayed block ack agreement or when it is carried in an A-MPDU.
@@ -1447,7 +1079,6 @@ QosTxop::NeedFragmentation (void) const
bool needTxopFragmentation = false;
if (GetTxopLimit ().IsStrictlyPositive () && m_currentHdr.IsData ())
{
needTxopFragmentation = (GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, m_currentParams) > GetTxopLimit ());
}
return (needTxopFragmentation || m_stationManager->NeedFragmentation (Create<const WifiMacQueueItem> (m_currentPacket, m_currentHdr)));
}
@@ -1482,19 +1113,6 @@ QosTxop::GetTxopFragmentSize (void) const
while (!found)
{
size = (minSize + ((maxSize - minSize) / 2));
if (GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, m_currentParams, size) > txopDuration)
{
maxSize = size;
}
else
{
minSize = size;
}
if (GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, m_currentParams, size) <= txopDuration
&& GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, m_currentParams, size + 1) > txopDuration)
{
found = true;
}
}
NS_ASSERT (size != 0);
return size;
@@ -1782,13 +1400,10 @@ QosTxop::SetupBlockAckIfNeeded (void)
Mac48Address recipient = m_currentHdr.GetAddr1 ();
uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, recipient);
if ((GetBlockAckThreshold () > 0 && packets >= GetBlockAckThreshold ())
|| (GetLow ()->GetMpduAggregator () != 0 && m_stationManager->GetHtSupported (recipient) && GetLow ()->GetMpduAggregator ()->GetMaxAmpduSize (recipient, tid, WIFI_MOD_CLASS_HT) > 0 && packets > 1)
|| m_stationManager->GetVhtSupported ()
|| m_stationManager->GetHeSupported ())
{
/* Block ack setup */
uint16_t startingSequence = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient);
SendAddBaRequest (recipient, tid, startingSequence, m_blockAckInactivityTimeout, true);
return true;
}
return false;
@@ -1799,8 +1414,6 @@ QosTxop::CompleteConfig (void)
{
NS_LOG_FUNCTION (this);
m_baManager->SetTxMiddle (m_txMiddle);
m_low->RegisterEdcaForAc (m_ac, this);
m_baManager->SetBlockAckInactivityCallback (MakeCallback (&QosTxop::SendDelbaFrame, this));
}
void
@@ -1831,103 +1444,6 @@ QosTxop::GetBlockAckInactivityTimeout (void) const
return m_blockAckInactivityTimeout;
}
void
QosTxop::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq,
uint16_t timeout, bool immediateBAck)
{
NS_LOG_FUNCTION (this << dest << +tid << startSeq << timeout << immediateBAck);
NS_LOG_DEBUG ("sent ADDBA request to " << dest);
WifiMacHeader hdr;
hdr.SetType (WIFI_MAC_MGT_ACTION);
hdr.SetAddr1 (dest);
hdr.SetAddr2 (m_low->GetAddress ());
hdr.SetAddr3 (m_low->GetBssid ());
hdr.SetDsNotTo ();
hdr.SetDsNotFrom ();
WifiActionHeader actionHdr;
WifiActionHeader::ActionValue action;
action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST;
actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
Ptr<Packet> packet = Create<Packet> ();
/*Setting ADDBARequest header*/
MgtAddBaRequestHeader reqHdr;
reqHdr.SetAmsduSupport (true);
if (immediateBAck)
{
reqHdr.SetImmediateBlockAck ();
}
else
{
reqHdr.SetDelayedBlockAck ();
}
reqHdr.SetTid (tid);
/* For now we don't use buffer size field in the ADDBA request frame. The recipient
* will choose how many packets it can receive under block ack.
*/
reqHdr.SetBufferSize (0);
reqHdr.SetTimeout (timeout);
reqHdr.SetStartingSequence (startSeq);
m_baManager->CreateAgreement (&reqHdr, dest);
packet->AddHeader (reqHdr);
packet->AddHeader (actionHdr);
m_currentPacket = packet;
m_currentHdr = hdr;
uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr);
m_currentHdr.SetSequenceNumber (sequence);
m_currentHdr.SetFragmentNumber (0);
m_currentHdr.SetNoMoreFragments ();
m_currentHdr.SetNoRetry ();
m_currentParams.EnableAck ();
m_currentParams.DisableRts ();
m_currentParams.DisableNextData ();
m_low->StartTransmission (Create<WifiMacQueueItem> (m_currentPacket, m_currentHdr), m_currentParams, this);
}
void
QosTxop::SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator)
{
NS_LOG_FUNCTION (this << addr << +tid << byOriginator);
WifiMacHeader hdr;
hdr.SetType (WIFI_MAC_MGT_ACTION);
hdr.SetAddr1 (addr);
hdr.SetAddr2 (m_low->GetAddress ());
hdr.SetAddr3 (m_low->GetBssid ());
hdr.SetDsNotTo ();
hdr.SetDsNotFrom ();
MgtDelBaHeader delbaHdr;
delbaHdr.SetTid (tid);
if (byOriginator)
{
delbaHdr.SetByOriginator ();
m_baManager->DestroyAgreement (addr, tid);
}
else
{
delbaHdr.SetByRecipient ();
m_low->DestroyBlockAckAgreement (addr, tid);
}
WifiActionHeader actionHdr;
WifiActionHeader::ActionValue action;
action.blockAck = WifiActionHeader::BLOCK_ACK_DELBA;
actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (delbaHdr);
packet->AddHeader (actionHdr);
PushFront (packet, hdr);
}
void
QosTxop::DoInitialize (void)
{

View File

@@ -115,14 +115,12 @@ public:
bool IsQosTxop (void) const;
void SetWifiRemoteStationManager (const Ptr<WifiRemoteStationManager> remoteManager);
virtual bool HasFramesToTransmit (void);
void NotifyAccessGranted (void);
void NotifyInternalCollision (void);
void GotAck (void);
void GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient,
double rxSnr, double dataSnr, WifiTxVector dataTxVector);
void MissedBlockAck (uint8_t nMpdus);
void MissedAck (void);
void StartNextPacket (void);
void EndTxNoAck (void);
void RestartAccessIfNeeded (void);
void StartAccessIfNeeded (void);
@@ -325,15 +323,6 @@ public:
* \return the BlockAck inactivity timeout.
*/
uint16_t GetBlockAckInactivityTimeout (void) const;
/**
* Sends DELBA frame to cancel a block ack agreement with STA
* addressed by <i>addr</i> for TID <i>tid</i>.
*
* \param addr address of the recipient.
* \param tid traffic ID.
* \param byOriginator flag to indicate whether this is set by the originator.
*/
void SendDelbaFrame (Mac48Address addr, uint8_t tid, bool byOriginator);
/**
* Stores an MPDU (part of an A-MPDU) in block ack agreement (i.e. the sender is waiting
* for a BlockAck containing the sequence number of this MPDU).
@@ -397,41 +386,6 @@ public:
* \return the next sequence number.
*/
uint16_t PeekNextSequenceNumberFor (const WifiMacHeader *hdr);
/**
* Peek the next frame to transmit to the given receiver and of the given
* TID from the block ack manager retransmit queue first and, if not found, from
* the EDCA queue. If <i>tid</i> is equal to 8 (invalid value) and <i>recipient</i>
* is the broadcast address, the first available frame is returned.
* Note that A-MSDU aggregation is never attempted (this is relevant if the
* frame is peeked from the EDCA queue). If the frame is peeked from the EDCA
* queue, it is assigned a sequence number peeked from MacTxMiddle.
*
* \param tid traffic ID.
* \param recipient the receiver station address.
* \returns the peeked frame.
*/
Ptr<const WifiMacQueueItem> PeekNextFrame (uint8_t tid = 8, Mac48Address recipient = Mac48Address::GetBroadcast ());
/**
* Dequeue the frame that has been previously peeked by calling PeekNextFrame.
* If the peeked frame is a QoS Data frame, it is actually dequeued if it meets
* the constraint on the maximum A-MPDU size (by assuming that the frame has to
* be aggregated to an existing A-MPDU of the given size) and its transmission
* time does not exceed the given PPDU duration limit (if distinct from Time::Min ()).
* If the peeked frame is a unicast QoS Data frame stored in the EDCA queue,
* attempt to perform A-MSDU aggregation (while meeting the constraints mentioned
* above) if <i>aggregate</i> is true and assign a sequence number to the
* dequeued frame.
*
* \param peekedItem the peeked frame.
* \param txVector the TX vector used to transmit the peeked frame
* \param aggregate whether to attempt A-MSDU aggregation
* \param ampduSize the size of the existing A-MPDU in bytes, if any
* \param ppduDurationLimit the limit on the PPDU duration
* \returns the dequeued frame.
*/
Ptr<WifiMacQueueItem> DequeuePeekedFrame (Ptr<const WifiMacQueueItem> peekedItem, WifiTxVector txVector,
bool aggregate = true, uint32_t ampduSize = 0,
Time ppduDurationLimit = Time::Min ());
/**
* Peek the next frame to transmit to the given receiver and of the given
* TID from the block ack manager retransmit queue first and, if not found, from
@@ -595,18 +549,6 @@ private:
* \return true if we tried to set up block ack, false otherwise.
*/
bool SetupBlockAckIfNeeded (void);
/**
* Sends an ADDBA Request to establish a block ack agreement with STA
* addressed by <i>recipient</i> for TID <i>tid</i>.
*
* \param recipient address of the recipient.
* \param tid traffic ID.
* \param startSeq starting sequence.
* \param timeout timeout value.
* \param immediateBAck flag to indicate whether immediate BlockAck is used.
*/
void SendAddBaRequest (Mac48Address recipient, uint8_t tid, uint16_t startSeq,
uint16_t timeout, bool immediateBAck);
/**
* Check if the given MPDU is to be considered old according to the current
* starting sequence number of the transmit window, provided that a block ack

View File

@@ -896,6 +896,19 @@ public:
*/
typedef void (*RateChangeTracedCallback)(DataRate oldRate, DataRate newRate, Mac48Address remoteAddress);
/**
* Return the WifiPhy.
*
* \return a pointer to the WifiPhy
*/
Ptr<WifiPhy> GetPhy (void) const;
/**
* Return the WifiMac.
*
* \return a pointer to the WifiMac
*/
Ptr<WifiMac> GetMac (void) const;
protected:
virtual void DoDispose (void);
@@ -1056,19 +1069,6 @@ protected:
*/
uint8_t GetNess (const WifiRemoteStation *station) const;
/**
* Return the WifiPhy.
*
* \return a pointer to the WifiPhy
*/
Ptr<WifiPhy> GetPhy (void) const;
/**
* Return the WifiMac.
*
* \return a pointer to the WifiMac
*/
Ptr<WifiMac> GetMac (void) const;
private:
/**