wifi: Enable protection for DL MU PPDUs including one PSDU
This commit is contained in:
committed by
Tom Henderson
parent
72c64cd500
commit
0816eebc29
@@ -810,28 +810,42 @@ FrameExchangeManager::CtsTimeout (Ptr<WifiMacQueueItem> rts, const WifiTxVector&
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *rts << txVector);
|
||||
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportRtsFailed (m_mpdu->GetHeader ());
|
||||
DoCtsTimeout (Create<WifiPsdu> (m_mpdu, true));
|
||||
m_mpdu = nullptr;
|
||||
}
|
||||
|
||||
if (!m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (m_mpdu))
|
||||
void
|
||||
FrameExchangeManager::DoCtsTimeout (Ptr<WifiPsdu> psdu)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *psdu);
|
||||
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportRtsFailed (psdu->GetHeader (0));
|
||||
|
||||
if (!m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (*psdu->begin ()))
|
||||
{
|
||||
NS_LOG_DEBUG ("Missed CTS, discard MPDU");
|
||||
// Dequeue the MPDU if it is stored in a queue
|
||||
DequeueMpdu (m_mpdu);
|
||||
NotifyPacketDiscarded (m_mpdu);
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportFinalRtsFailed (m_mpdu->GetHeader ());
|
||||
NS_LOG_DEBUG ("Missed CTS, discard MPDU(s)");
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportFinalRtsFailed (psdu->GetHeader (0));
|
||||
for (const auto& mpdu : *PeekPointer (psdu))
|
||||
{
|
||||
// Dequeue the MPDU if it is stored in a queue
|
||||
DequeueMpdu (mpdu);
|
||||
NotifyPacketDiscarded (mpdu);
|
||||
}
|
||||
m_dcf->ResetCw ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Missed CTS, retransmit RTS");
|
||||
NS_LOG_DEBUG ("Missed CTS, retransmit MPDU(s)");
|
||||
m_dcf->UpdateFailedCw ();
|
||||
}
|
||||
// Make the sequence number of the MPDU available again if the MPDU has never
|
||||
// been transmitted, both in case the MPDU has been discarded and in case the
|
||||
// MPDU has to be transmitted (because a new sequence number is assigned to
|
||||
// Make the sequence numbers of the MPDUs available again if the MPDUs have never
|
||||
// been transmitted, both in case the MPDUs have been discarded and in case the
|
||||
// MPDUs have to be transmitted (because a new sequence number is assigned to
|
||||
// MPDUs that have never been transmitted and are selected for transmission)
|
||||
ReleaseSequenceNumber (m_mpdu);
|
||||
m_mpdu = 0;
|
||||
for (const auto& mpdu : *PeekPointer (psdu))
|
||||
{
|
||||
ReleaseSequenceNumber (mpdu);
|
||||
}
|
||||
TransmissionFailed ();
|
||||
}
|
||||
|
||||
|
||||
@@ -531,6 +531,13 @@ protected:
|
||||
* \param txVector the TXVECTOR used to transmit the RTS frame
|
||||
*/
|
||||
virtual void CtsTimeout (Ptr<WifiMacQueueItem> rts, const WifiTxVector& txVector);
|
||||
/**
|
||||
* Take required actions when the CTS timer fired after sending an RTS to
|
||||
* protect the given PSDU expires.
|
||||
*
|
||||
* \param psdu the PSDU protected by the failed RTS
|
||||
*/
|
||||
void DoCtsTimeout (Ptr<WifiPsdu> psdu);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
||||
@@ -227,7 +227,12 @@ HeFrameExchangeManager::SendPsduMapWithProtection (WifiPsduMap psduMap, WifiTxPa
|
||||
WifiAckManager::SetQosAckPolicy (psdu.second, m_txParams.m_acknowledgment.get ());
|
||||
}
|
||||
|
||||
if (m_txParams.m_protection->method == WifiProtection::NONE)
|
||||
if (m_txParams.m_protection->method == WifiProtection::RTS_CTS)
|
||||
{
|
||||
NS_ABORT_MSG_IF (m_psduMap.size () > 1, "Cannot use RTS/CTS with MU PPDUs");
|
||||
SendRts (m_txParams);
|
||||
}
|
||||
else if (m_txParams.m_protection->method == WifiProtection::NONE)
|
||||
{
|
||||
SendPsduMap ();
|
||||
}
|
||||
@@ -250,6 +255,24 @@ HeFrameExchangeManager::GetPsduTo (Mac48Address to, const WifiPsduMap& psduMap)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
HeFrameExchangeManager::CtsTimeout (Ptr<WifiMacQueueItem> rts, const WifiTxVector& txVector)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *rts << txVector);
|
||||
|
||||
if (m_psduMap.empty ())
|
||||
{
|
||||
// A CTS Timeout occurred when protecting a single PSDU that is not included
|
||||
// in a DL MU PPDU is handled by the parent classes
|
||||
VhtFrameExchangeManager::CtsTimeout (rts, txVector);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ABORT_MSG_IF (m_psduMap.size () > 1, "RTS/CTS cannot be used to protect an MU PPDU");
|
||||
DoCtsTimeout (m_psduMap.begin ()->second);
|
||||
m_psduMap.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
HeFrameExchangeManager::SendPsduMap (void)
|
||||
{
|
||||
@@ -1455,7 +1478,26 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr<WifiMacQueueItem> mpdu, RxSignalInfo rx
|
||||
|
||||
if (hdr.IsCtl ())
|
||||
{
|
||||
if (hdr.IsAck () && m_txTimer.IsRunning ()
|
||||
if (hdr.IsCts () && m_txTimer.IsRunning () && m_txTimer.GetReason () == WifiTxTimer::WAIT_CTS
|
||||
&& m_psduMap.size () == 1)
|
||||
{
|
||||
NS_ABORT_MSG_IF (inAmpdu, "Received CTS as part of an A-MPDU");
|
||||
NS_ASSERT (hdr.GetAddr1 () == m_self);
|
||||
|
||||
Mac48Address sender = m_psduMap.begin ()->second->GetAddr1 ();
|
||||
NS_LOG_DEBUG ("Received CTS from=" << sender);
|
||||
|
||||
SnrTag tag;
|
||||
mpdu->GetPacket ()->PeekPacketTag (tag);
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportRxOk (sender, rxSignalInfo, txVector);
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportRtsOk (m_psduMap.begin ()->second->GetHeader (0),
|
||||
rxSignalInfo.snr, txVector.GetMode (), tag.Get ());
|
||||
|
||||
m_txTimer.Cancel ();
|
||||
m_channelAccessManager->NotifyCtsTimeoutResetNow ();
|
||||
Simulator::Schedule (m_phy->GetSifs (), &HeFrameExchangeManager::SendPsduMap, this);
|
||||
}
|
||||
else if (hdr.IsAck () && m_txTimer.IsRunning ()
|
||||
&& m_txTimer.GetReason () == WifiTxTimer::WAIT_NORMAL_ACK_AFTER_DL_MU_PPDU)
|
||||
{
|
||||
NS_ASSERT (hdr.GetAddr1 () == m_self);
|
||||
|
||||
@@ -101,6 +101,7 @@ protected:
|
||||
Time GetTxDuration (uint32_t ppduPayloadSize, Mac48Address receiver,
|
||||
const WifiTxParameters& txParams) const override;
|
||||
bool SendMpduFromBaManager (Ptr<QosTxop> edca, Time availableTime, bool initialFrame) override;
|
||||
void CtsTimeout (Ptr<WifiMacQueueItem> rts, const WifiTxVector& txVector) override;
|
||||
|
||||
/**
|
||||
* Send a map of PSDUs as a DL MU PPDU.
|
||||
|
||||
@@ -768,36 +768,8 @@ HtFrameExchangeManager::CtsTimeout (Ptr<WifiMacQueueItem> rts, const WifiTxVecto
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERT (m_psdu->GetNMpdus () > 1);
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportRtsFailed (m_psdu->GetHeader (0));
|
||||
|
||||
if (!m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (*m_psdu->begin ()))
|
||||
{
|
||||
NS_LOG_DEBUG ("Missed CTS, discard MPDUs");
|
||||
m_mac->GetWifiRemoteStationManager ()->ReportFinalRtsFailed (m_psdu->GetHeader (0));
|
||||
// Dequeue the MPDUs if they are stored in a queue
|
||||
DequeuePsdu (m_psdu);
|
||||
for (const auto& mpdu : *PeekPointer (m_psdu))
|
||||
{
|
||||
NotifyPacketDiscarded (mpdu);
|
||||
}
|
||||
m_edca->ResetCw ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Missed CTS, retransmit MPDUs");
|
||||
m_edca->UpdateFailedCw ();
|
||||
}
|
||||
// Make the sequence numbers of the MPDUs available again if the MPDUs have never
|
||||
// been transmitted, both in case the MPDUs have been discarded and in case the
|
||||
// MPDUs have to be transmitted (because a new sequence number is assigned to
|
||||
// MPDUs that have never been transmitted and are selected for transmission)
|
||||
for (const auto& mpdu : *PeekPointer (m_psdu))
|
||||
{
|
||||
ReleaseSequenceNumber (mpdu);
|
||||
}
|
||||
m_psdu = 0;
|
||||
TransmissionFailed ();
|
||||
DoCtsTimeout (m_psdu);
|
||||
m_psdu = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user