wifi: QosTxop sends peeked non-broadcast QoS Data frames to MacLow

This commit is contained in:
Stefano Avallone
2019-04-03 17:14:39 +02:00
parent 561ed7cf95
commit 1ef995ce3b
3 changed files with 109 additions and 41 deletions

View File

@@ -529,15 +529,17 @@ MacLow::StartTransmission (Ptr<WifiMacQueueItem> mpdu,
/* The packet received by this function can be any of the following:
* (a) a management frame dequeued from the Txop
* (b) a non-QoS data frame dequeued from the Txop
* (c) a QoS data or DELBA Request frame dequeued from a QosTxop
* (d) a BlockAckReq or ADDBA Request frame
* (c) a non-broadcast QoS Data frame peeked or dequeued from a QosTxop
* (d) a broadcast QoS data or DELBA Request frame dequeued from a QosTxop
* (e) a BlockAckReq or ADDBA Request frame
* (f) a fragment of non-QoS/QoS Data frame dequeued from the Txop/QosTxop
*/
if (hdr.IsQosData () && !hdr.GetAddr1 ().IsBroadcast ())
if (hdr.IsQosData () && !hdr.GetAddr1 ().IsBroadcast ()
&& !hdr.IsMoreFragments () && hdr.GetFragmentNumber () == 0)
{
// We get here if the received packet is a non-broadcast QoS data frame
uint8_t tid = GetTid (mpdu->GetPacket (), hdr);
uint8_t tid = hdr.GetQosTid ();
Ptr<QosTxop> qosTxop = m_edca.find (QosUtilsMapTidToAc (tid))->second;
std::vector<Ptr<WifiMacQueueItem>> mpduList;
// if a TXOP limit exists, compute the remaining TXOP duration
Time txopLimit = Seconds (0);
@@ -547,10 +549,43 @@ MacLow::StartTransmission (Ptr<WifiMacQueueItem> mpdu,
NS_ASSERT (txopLimit.IsPositive ());
}
// QosTxop may send us a peeked frame
Ptr<const WifiMacQueueItem> tmp = qosTxop->PeekNextFrame ();
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))
{
newMpdu = mpdu;
}
if (newMpdu == 0)
{
// if the frame has been dequeued, then there is no BA agreement with the
// receiver (otherwise the frame would have been peeked). Hence, the frame
// has been sent under Normal Ack policy, not acknowledged and now retransmitted.
// If we cannot send it now, let the QosTxop retransmit it again.
// If the frame has been just peeked, reset the current packet at QosTxop.
if (isPeeked)
{
qosTxop->UpdateCurrentPacket (Create<WifiMacQueueItem> (nullptr, WifiMacHeader ()));
}
return;
}
// Update the current packet at QosTxop, given that A-MSDU aggregation may have
// been performed on the peeked frame
qosTxop->UpdateCurrentPacket (newMpdu);
//Perform MPDU aggregation if possible
std::vector<Ptr<WifiMacQueueItem>> mpduList;
if (m_mpduAggregator != 0)
{
mpduList = m_mpduAggregator->GetNextAmpdu (mpdu, m_currentTxVector, txopLimit);
mpduList = m_mpduAggregator->GetNextAmpdu (newMpdu, m_currentTxVector, txopLimit);
}
if (mpduList.size () > 1)
@@ -564,11 +599,15 @@ MacLow::StartTransmission (Ptr<WifiMacQueueItem> mpdu,
|| m_currentTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HE)
{
// VHT/HE single MPDU
m_currentPacket = Create<WifiPsdu> (mpdu, true);
m_currentPacket = Create<WifiPsdu> (newMpdu, true);
NS_LOG_DEBUG ("tx unicast S-MPDU with sequence number " << hdr.GetSequenceNumber ());
qosTxop->SetAmpduExist (hdr.GetAddr1 (), true);
}
else // HT
{
m_currentPacket = Create<WifiPsdu> (newMpdu, false);
}
// A QoS Txop must have an installed ack policy selector
NS_ASSERT (qosTxop->GetAckPolicySelector () != 0);

View File

@@ -459,6 +459,15 @@ QosTxop::GetTransmissionParameters (Ptr<const WifiMacQueueItem> frame) const
return params;
}
void
QosTxop::UpdateCurrentPacket (Ptr<WifiMacQueueItem> mpdu)
{
NS_LOG_FUNCTION (this << *mpdu);
m_currentPacket = mpdu->GetPacket ();
m_currentHdr = mpdu->GetHeader ();
m_currentPacketTimestamp = mpdu->GetTimeStamp ();
}
void
QosTxop::NotifyAccessGranted (void)
{
@@ -506,18 +515,31 @@ QosTxop::NotifyAccessGranted (void)
}
m_stationManager->UpdateFragmentationThreshold ();
Time ppduDurationLimit = Seconds (0);
// compute the limit on the PPDU duration due to the TXOP duration, if any
if (peekedItem->GetHeader ().IsQosData () && GetTxopLimit ().IsStrictlyPositive ())
Ptr<WifiMacQueueItem> item;
// non-broadcast 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-broadcast QoS data frame. MacLow will be in charge of
// computing the correct limits and dequeue the frame.
if (peekedItem->GetHeader ().IsQosData () && !peekedItem->GetHeader ().GetAddr1 ().IsBroadcast ()
&& !NeedFragmentation ())
{
MacLowTransmissionParameters params = GetTransmissionParameters (peekedItem);
ppduDurationLimit = GetTxopRemaining () - m_low->CalculateOverheadTxTime (peekedItem, params);
item = Copy (peekedItem);
}
else
{
// compute the limit on the PPDU duration due to the TXOP duration, if any
Time ppduDurationLimit = Seconds (0);
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
Ptr<WifiMacQueueItem> item = DequeuePeekedFrame (peekedItem, m_low->GetDataTxVector (peekedItem),
!NeedFragmentation (), 0, ppduDurationLimit);
// 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)
{
@@ -549,15 +571,6 @@ QosTxop::NotifyAccessGranted (void)
{
m_currentParams = GetTransmissionParameters (mpdu);
// check if the current frame meets the QoS TXOP Limit, if any
if (mpdu->GetHeader ().IsQosData () && GetTxopLimit ().IsStrictlyPositive () &&
m_low->CalculateOverallTxTime (mpdu->GetPacket (), &mpdu->GetHeader (),
m_currentParams) > GetTxopRemaining ())
{
NS_LOG_DEBUG ("Not enough time in the current TXOP");
return;
}
//With COMPRESSED_BLOCK_ACK fragmentation must be avoided.
if (((m_currentHdr.IsQosData () && !m_currentHdr.IsQosAmsdu ())
|| (m_currentHdr.IsData () && !m_currentHdr.IsQosData ()))
@@ -1080,14 +1093,22 @@ QosTxop::StartNextPacket (void)
return;
}
// when dequeuing the peeked packet, A-MSDU aggregation is attempted if the
// packet has been peeked from the EDCA queue. Thus, compute the max available
// time for the transmission of the PPDU
Time maxPpduDuration = GetTxopRemaining () - m_low->CalculateOverheadTxTime (nextFrame, params);
NS_ASSERT (maxPpduDuration.IsPositive ());
Ptr<WifiMacQueueItem> item;
// non-broadcast 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-broadcast QoS data frame. MacLow will be in charge of
// computing the correct limits and dequeue the frame.
if (nextFrame->GetHeader ().IsQosData () && !nextFrame->GetHeader ().GetAddr1 ().IsBroadcast ())
{
item = Create<WifiMacQueueItem> (*nextFrame);
}
else
{
// dequeue the peeked frame
item = DequeuePeekedFrame (nextFrame, m_low->GetDataTxVector (nextFrame));
}
Ptr<WifiMacQueueItem> item = DequeuePeekedFrame (nextFrame, m_low->GetDataTxVector (nextFrame),
true, 0, maxPpduDuration);
NS_ASSERT (item != 0);
NS_LOG_DEBUG ("start next packet " << *item << " within the current TXOP");
m_currentPacket = item->GetPacket ();

View File

@@ -423,15 +423,15 @@ public:
*/
Ptr<const WifiMacQueueItem> PeekNextFrame (uint8_t tid = 8, Mac48Address recipient = Mac48Address::GetBroadcast ());
/**
* Dequeue the frame that has been previously peeked by calling PeekNextFrame
* or PeekNextFrameByTidAndAddress. 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 strictly positive). 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.
* 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 strictly positive).
* 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
@@ -452,6 +452,14 @@ public:
*/
MacLowTransmissionParameters GetTransmissionParameters (Ptr<const WifiMacQueueItem> frame) const;
/**
* Update the current packet this QosTxop is trying to transmit. This method
* is typically called by MacLow when it changes (i.e., by performing A-MSDU
* aggregation) the packet received from this QosTxop.
*
* \param mpdu the MPDU that MacLow is forwarding down to the PHY.
*/
void UpdateCurrentPacket (Ptr<WifiMacQueueItem> mpdu);
/**
* The packet we sent was successfully received by the receiver.
*