wifi: QosTxop sends peeked non-broadcast QoS Data frames to MacLow
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user