Bug 2075 [wifi] - A-MPDU using RTS/CTS behaves wrongly when MaxSsrc is reached

This commit is contained in:
Sébastien Deronne
2015-05-05 00:29:40 +02:00
parent 60b507ccdf
commit d0ec938b42
4 changed files with 92 additions and 4 deletions

View File

@@ -40,6 +40,7 @@ Bugs fixed
- Bug 2066 - A-MPDU reception should check for successful preamble
- Bug 2070 - Wrong report of Packets and Bytes stored in CoDeL
- Bug 2073 - NDisc cache entries update timer might be stuck in a loop
- Bug 2075 - A-MPDU using RTS/CTS behaves wrongly when MaxSsrc is reached
- Bug 2076 - TCP MinRTO Attribute is not actually used
- Bug 2077 - Icmpv6L4Protocol::HandleDestinationUnreachable must check the packet size, not its serialized size
- Bug 2079 - mcs variable in ht-wifi-network example is confusing

View File

@@ -659,9 +659,35 @@ EdcaTxopN::MissedCts (void)
if (GetAmpduExist())
{
m_low->FlushAggregateQueue ();
NS_LOG_DEBUG ("Transmit Block Ack Request");
CtrlBAckRequestHeader reqHdr;
reqHdr.SetType (COMPRESSED_BLOCK_ACK);
uint8_t tid = m_currentHdr.GetQosTid ();
reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberfor (&m_currentHdr));
reqHdr.SetTidInfo (tid);
reqHdr.SetHtImmediateAck(true);
Ptr<Packet> bar = Create<Packet> ();
bar->AddHeader (reqHdr);
Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck());
m_currentBar = request;
WifiMacHeader hdr;
hdr.SetType (WIFI_MAC_CTL_BACKREQ);
hdr.SetAddr1 (request.recipient);
hdr.SetAddr2 (m_low->GetAddress ());
hdr.SetAddr3 (m_low->GetBssid ());
hdr.SetDsNotTo ();
hdr.SetDsNotFrom ();
hdr.SetNoRetry ();
hdr.SetNoMoreFragments ();
m_currentPacket = request.bar;
m_currentHdr = hdr;
}
else
{
m_currentPacket = 0;
}
// to reset the dcf.
m_currentPacket = 0;
m_dcf->ResetCw ();
}
else

View File

@@ -913,7 +913,8 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamb
rxSnr, txMode);
m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
rxSnr, txMode, tag.Get ());
FlushAggregateQueue();
bool gotAck = false;
if (m_txParams.MustWaitNormalAck ()
&& m_normalAckTimeoutEvent.IsRunning ())
@@ -951,6 +952,7 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamb
m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 (),txMode);
m_sentMpdus = 0;
m_ampdu = false;
FlushAggregateQueue();
}
else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
{
@@ -1576,6 +1578,7 @@ MacLow::NormalAckTimeout (void)
m_listener = 0;
m_sentMpdus = 0;
m_ampdu = false;
FlushAggregateQueue();
listener->MissedAck ();
}
void
@@ -1606,6 +1609,7 @@ MacLow::BlockAckTimeout (void)
m_listener = 0;
m_sentMpdus = 0;
m_ampdu = false;
FlushAggregateQueue();
listener->MissedBlockAck ();
}
void
@@ -1992,6 +1996,19 @@ MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode)
NS_ASSERT (m_currentPacket != 0);
WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket, &m_currentHdr);
if (m_aggregateQueue->GetSize () != 0)
{
for(int i = 0; i < m_txPackets.size(); i++)
{
uint8_t tid = GetTid (m_txPackets.at(i).packet, m_txPackets.at(i).hdr);
AcIndex ac = QosUtilsMapTidToAc (tid);
std::map<AcIndex, MacLowAggregationCapableTransmissionListener*>::const_iterator listenerIt= m_edcaListeners.find(ac);
listenerIt->second->CompleteMpduTx (m_txPackets.at(i).packet, m_txPackets.at(i).hdr, m_txPackets.at(i).timestamp);
}
m_txPackets.clear ();
}
WifiPreamble preamble;
if (m_phy->GetGreenfield() && m_stationManager->GetGreenfieldSupported (m_currentHdr.GetAddr1 ()))
//In the future has to make sure that receiver has greenfield enabled
@@ -2743,13 +2760,27 @@ MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr)
m_aggregateQueue->Enqueue (aggPacket, peekedHdr);
if (i == 1 && hdr.IsQosData ())
{
listenerIt->second->CompleteMpduTx (packet, hdr, tstamp);
if (!m_txParams.MustSendRts ())
{
listenerIt->second->CompleteMpduTx (packet, hdr, tstamp);
}
else
{
InsertInTxQueue (packet, hdr, tstamp);
}
}
NS_LOG_DEBUG ("Adding packet with Sequence number " << peekedHdr.GetSequenceNumber()<<" to A-MPDU, packet size = " << newPacket->GetSize ()<< ", A-MPDU size = " << currentAggregatedPacket->GetSize ());
i++;
isAmpdu = true;
m_sentMpdus++;
listenerIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
if (!m_txParams.MustSendRts ())
{
listenerIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
}
else
{
InsertInTxQueue (peekedPacket, peekedHdr, tstamp);
}
if (retry)
listenerIt->second->RemoveFromBaQueue(tid, hdr.GetAddr1 (), peekedHdr.GetSequenceNumber ());
else
@@ -2849,6 +2880,19 @@ MacLow::FlushAggregateQueue (void)
{
NS_LOG_DEBUG("Flush aggregate queue");
m_aggregateQueue->Flush ();
m_txPackets.clear ();
}
void
MacLow::InsertInTxQueue (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp)
{
Item item;
item.packet = packet;
item.hdr = hdr;
item.timestamp = tStamp;
m_txPackets.push_back (item);
}
Ptr<Packet>

View File

@@ -1255,6 +1255,11 @@ private:
*
*/
bool IsAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr);
/**
* Insert in a temporary queue.
* It is only used with a RTS/CTS exchange for an A-MPDU transmission.
*/
void InsertInTxQueue (Ptr<const Packet> packet, const WifiMacHeader &hdr, Time tStamp);
/**
* Perform MSDU aggregation for a given MPDU in an A-MPDU
*
@@ -1272,6 +1277,17 @@ private:
Ptr<WifiPhy> m_phy; //!< Pointer to WifiPhy (actually send/receives frames)
Ptr<WifiRemoteStationManager> m_stationManager; //!< Pointer to WifiRemoteStationManager (rate control)
MacLowRxCallback m_rxCallback; //!< Callback to pass packet up
/**
* A struct for packet, Wifi header, and timestamp.
*/
typedef struct
{
Ptr<const Packet> packet;
WifiMacHeader hdr;
Time timestamp;
} Item;
/**
* typedef for an iterator for a list of MacLowDcfListener.
*/
@@ -1346,6 +1362,7 @@ private:
Ptr<WifiMacQueue> m_aggregateQueue; //!< Queue used for MPDU aggregation
WifiMode m_currentMode; //!< mode 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<Item> 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.
};
} // namespace ns3