wifi: (fixes #2528) Improve 802.11n RIFS support

This commit is contained in:
Sébastien Deronne
2017-02-02 19:02:01 +01:00
parent af1dc022b1
commit 908d87fba6
12 changed files with 187 additions and 39 deletions

View File

@@ -41,6 +41,7 @@ Bugs fixed
- Bug 2518 - Suppress printing of list of modules for Python programs
- Bug 2521 - Include ipv6-option.h in wscript
- Bug 2527 - PrintRoutingTable extended to add an optional Time::Units parameter
- Bug 2528 - 802.11n RIFS cannot be enabled
- Bug 2529 - Missing trace when Block ACK timeout is triggered or when missing MPDUs are announced by a Block ACK response
- Bug 2530 - Rename aodv::SetBalckListTimeout to aodv::SetBlackListTimeout
- Bug 2532 - Inconsistencies between 802.11n MCS and NSS value reported in TXVECTOR

View File

@@ -68,6 +68,11 @@ ApWifiMac::GetTypeId (void)
BooleanValue (true),
MakeBooleanAccessor (&ApWifiMac::m_enableNonErpProtection),
MakeBooleanChecker ())
.AddAttribute ("RifsMode", "If non-HT STAs are detected, whether to force RIFS to be disabled within the BSS."
"This parameter is only used when HT is supported by the AP.",
BooleanValue (true),
MakeBooleanAccessor (&ApWifiMac::m_disableRifs),
MakeBooleanChecker ())
;
return tid;
}
@@ -511,6 +516,7 @@ ApWifiMac::GetHtOperation (void) const
if (m_htSupported)
{
operation.SetHtSupported (1);
operation.SetRifsMode (GetRifsMode ());
operation.SetNonGfHtStasPresent (IsNonGfHtStasPresent ());
if (m_nonHtStations.empty ())
{
@@ -1143,4 +1149,26 @@ ApWifiMac::GetUseNonErpProtection (void) const
return useProtection;
}
bool
ApWifiMac::GetRifsMode (void) const
{
bool rifsMode = false;
if (m_htSupported && !m_vhtSupported) //RIFS mode is forbidden for VHT
{
if (m_nonHtStations.empty () || !m_disableRifs)
{
rifsMode = true;
}
}
if (GetRifsSupported () && rifsMode)
{
m_stationManager->SetRifsPermitted (true);
}
else
{
m_stationManager->SetRifsPermitted (false);
}
return rifsMode;
}
} //namespace ns3

View File

@@ -265,6 +265,13 @@ private:
* false otherwise
*/
bool GetUseNonErpProtection (void) const;
/**
* Return whether RIFS is allowed in the BSS.
*
* \return true if RIFS is allowed in the BSS,
* false otherwise
*/
bool GetRifsMode (void) const;
virtual void DoDispose (void);
virtual void DoInitialize (void);
@@ -279,6 +286,7 @@ private:
std::list<Mac48Address> m_nonErpStations; //!< List of all non-ERP stations currently associated to the AP
std::list<Mac48Address> m_nonHtStations; //!< List of all non-HT stations currently associated to the AP
bool m_enableNonErpProtection; //!< Flag whether protection mechanism is used or not when non-ERP STAs are present within the BSS
bool m_disableRifs; //!< Flag whether to force RIFS to be disabled within the BSS If non-HT STAs are detected
};
} //namespace ns3

View File

@@ -266,7 +266,7 @@ MacLow::MacLow ()
m_sendCtsEvent (),
m_sendAckEvent (),
m_sendDataEvent (),
m_waitSifsEvent (),
m_waitIfsEvent (),
m_endTxNoAckEvent (),
m_currentPacket (0),
m_currentDca (0),
@@ -332,9 +332,8 @@ MacLow::DoDispose (void)
m_sendCtsEvent.Cancel ();
m_sendAckEvent.Cancel ();
m_sendDataEvent.Cancel ();
m_waitSifsEvent.Cancel ();
m_waitIfsEvent.Cancel ();
m_endTxNoAckEvent.Cancel ();
m_waitRifsEvent.Cancel ();
m_phy = 0;
m_stationManager = 0;
if (m_phyMacLowListener != 0)
@@ -399,14 +398,9 @@ MacLow::CancelAllEvents (void)
m_sendDataEvent.Cancel ();
oneRunning = true;
}
if (m_waitSifsEvent.IsRunning ())
if (m_waitIfsEvent.IsRunning ())
{
m_waitSifsEvent.Cancel ();
oneRunning = true;
}
if (m_waitRifsEvent.IsRunning ())
{
m_waitRifsEvent.Cancel ();
m_waitIfsEvent.Cancel ();
oneRunning = true;
}
if (m_endTxNoAckEvent.IsRunning ())
@@ -921,13 +915,25 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, bool
}
if (m_txParams.HasNextPacket ())
{
m_waitSifsEvent = Simulator::Schedule (GetSifs (),
&MacLow::WaitSifsAfterEndTxFragment, this);
if (m_stationManager->GetRifsPermitted ())
{
m_waitIfsEvent = Simulator::Schedule (GetRifs (), &MacLow::WaitIfsAfterEndTxFragment, this);
}
else
{
m_waitIfsEvent = Simulator::Schedule (GetSifs (), &MacLow::WaitIfsAfterEndTxFragment, this);
}
}
else if (m_currentHdr.IsQosData () && m_currentDca->HasTxop ())
{
m_waitSifsEvent = Simulator::Schedule (GetSifs (),
&MacLow::WaitSifsAfterEndTxPacket, this);
if (m_stationManager->GetRifsPermitted ())
{
m_waitIfsEvent = Simulator::Schedule (GetRifs (), &MacLow::WaitIfsAfterEndTxPacket, this);
}
else
{
m_waitIfsEvent = Simulator::Schedule (GetSifs (), &MacLow::WaitIfsAfterEndTxPacket, this);
}
}
m_ampdu = false;
if (m_currentHdr.IsQosData ())
@@ -951,9 +957,14 @@ MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, bool
m_ampdu = false;
if (m_currentHdr.IsQosData () && m_currentDca->HasTxop ())
{
m_waitSifsEvent = Simulator::Schedule (GetSifs (),
&MacLow::WaitSifsAfterEndTxPacket,
this);
if (m_stationManager->GetRifsPermitted ())
{
m_waitIfsEvent = Simulator::Schedule (GetRifs (), &MacLow::WaitIfsAfterEndTxPacket, this);
}
else
{
m_waitIfsEvent = Simulator::Schedule (GetSifs (), &MacLow::WaitIfsAfterEndTxPacket, this);
}
}
}
else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
@@ -1747,23 +1758,30 @@ MacLow::StartDataTxTimers (WifiTxVector dataTxVector)
}
else if (m_txParams.HasNextPacket ())
{
if (m_stationManager->HasHtSupported ())
NS_ASSERT (m_waitIfsEvent.IsExpired ());
Time delay = txDuration;
if (m_stationManager->GetRifsPermitted ())
{
Time delay = txDuration + GetRifs ();
NS_ASSERT (m_waitRifsEvent.IsExpired ());
m_waitRifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTxFragment, this);
delay += GetRifs ();
}
else
{
Time delay = txDuration + GetSifs ();
NS_ASSERT (m_waitSifsEvent.IsExpired ());
m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTxFragment, this);
delay += GetSifs ();
}
m_waitIfsEvent = Simulator::Schedule (delay, &MacLow::WaitIfsAfterEndTxFragment, this);
}
else if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck () && m_currentDca->HasTxop ())
{
Time delay = txDuration + GetSifs ();
m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTxPacket, this);
Time delay = txDuration;
if (m_stationManager->GetRifsPermitted ())
{
delay += GetRifs ();
}
else
{
delay += GetSifs ();
}
m_waitIfsEvent = Simulator::Schedule (delay, &MacLow::WaitIfsAfterEndTxPacket, this);
}
else
{
@@ -1805,7 +1823,14 @@ MacLow::SendDataPacket (void)
}
if (m_txParams.HasNextPacket ())
{
duration += GetSifs ();
if (m_stationManager->GetRifsPermitted ())
{
duration += GetRifs ();
}
else
{
duration += GetSifs ();
}
duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
m_currentTxVector, m_phy->GetFrequency ());
if (m_txParams.MustWaitAck ())
@@ -1998,8 +2023,14 @@ MacLow::SendDataAfterCts (Mac48Address source, Time duration)
}
if (m_txParams.HasNextPacket ())
{
newDuration += GetSifs ();
newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), m_currentTxVector, m_phy->GetFrequency ());
if (m_stationManager->GetRifsPermitted ())
{
newDuration += GetRifs ();
}
else
{
newDuration += GetSifs ();
} newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), m_currentTxVector, m_phy->GetFrequency ());
if (m_txParams.MustWaitCompressedBlockAck ())
{
newDuration += GetSifs ();
@@ -2035,13 +2066,13 @@ MacLow::SendDataAfterCts (Mac48Address source, Time duration)
}
void
MacLow::WaitSifsAfterEndTxFragment (void)
MacLow::WaitIfsAfterEndTxFragment (void)
{
m_currentDca->StartNextFragment ();
}
void
MacLow::WaitSifsAfterEndTxPacket (void)
MacLow::WaitIfsAfterEndTxPacket (void)
{
m_currentDca->StartNextPacket ();
}

View File

@@ -883,8 +883,8 @@ private:
* Event handler that is usually scheduled to fired at the appropriate time
* after completing transmissions.
*/
void WaitSifsAfterEndTxFragment (void);
void WaitSifsAfterEndTxPacket (void);
void WaitIfsAfterEndTxFragment (void);
void WaitIfsAfterEndTxPacket (void);
/**
* A transmission that does not require an ACK has completed.
@@ -1062,10 +1062,9 @@ private:
EventId m_sendCtsEvent; //!< Event to send CTS
EventId m_sendAckEvent; //!< Event to send ACK
EventId m_sendDataEvent; //!< Event to send DATA
EventId m_waitSifsEvent; //!< Wait for SIFS event
EventId m_waitIfsEvent; //!< Wait for IFS event
EventId m_endTxNoAckEvent; //!< Event for finishing transmission that does not require ACK
EventId m_navCounterResetCtsMissed; //!< Event to reset NAV when CTS is not received
EventId m_waitRifsEvent; //!< Wait for RIFS event
Ptr<Packet> m_currentPacket; //!< Current packet transmitted/to be transmitted
WifiMacHeader m_currentHdr; //!< Header of the current transmitted packet

View File

@@ -825,6 +825,19 @@ RegularWifiMac::GetShortSlotTimeSupported (void) const
return m_shortSlotTimeSupported;
}
void
RegularWifiMac::SetRifsSupported (bool enable)
{
NS_LOG_FUNCTION (this << enable);
m_rifsSupported = enable;
}
bool
RegularWifiMac::GetRifsSupported (void) const
{
return m_rifsSupported;
}
void
RegularWifiMac::Enqueue (Ptr<const Packet> packet,
Mac48Address to, Mac48Address from)
@@ -1168,8 +1181,14 @@ RegularWifiMac::GetTypeId (void)
.AddAttribute ("ShortSlotTimeSupported",
"Whether or not short slot time is supported (only used by ERP APs or STAs).",
BooleanValue (true),
MakeBooleanAccessor (&WifiMac::GetShortSlotTimeSupported,
&WifiMac::SetShortSlotTimeSupported),
MakeBooleanAccessor (&RegularWifiMac::GetShortSlotTimeSupported,
&RegularWifiMac::SetShortSlotTimeSupported),
MakeBooleanChecker ())
.AddAttribute ("RifsSupported",
"Whether or not RIFS is supported (only used by HT APs or STAs).",
BooleanValue (false),
MakeBooleanAccessor (&RegularWifiMac::GetRifsSupported,
&RegularWifiMac::SetRifsSupported),
MakeBooleanChecker ())
.AddAttribute ("DcaTxop",
"The DcaTxop object.",

View File

@@ -137,6 +137,20 @@ public:
* false otherwise.
*/
virtual bool GetShortSlotTimeSupported (void) const;
/**
* Enable or disable RIFS feature.
*
* \param enable true if RIFS is to be supported,
* false otherwise
*/
virtual void SetRifsSupported (bool enable);
/**
* \return whether the device supports RIFS capability.
*
* \return true if short RIFS is supported,
* false otherwise.
*/
virtual bool GetRifsSupported (void) const;
/**
* \return the MAC address associated to this MAC layer.
@@ -598,6 +612,7 @@ private:
TracedCallback<const WifiMacHeader &> m_txErrCallback;
bool m_shortSlotTimeSupported;
bool m_rifsSupported;
};
} //namespace ns3

View File

@@ -584,6 +584,14 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
{
m_stationManager->SetUseGreenfieldProtection (false);
}
if (!m_vhtSupported && GetRifsSupported () && htOperation.GetRifsMode ())
{
m_stationManager->SetRifsPermitted (true);
}
else
{
m_stationManager->SetRifsPermitted (false);
}
for (uint32_t i = 0; i < m_phy->GetNMcs (); i++)
{
WifiMode mcs = m_phy->GetMcs (i);
@@ -808,6 +816,14 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
{
m_stationManager->SetUseGreenfieldProtection (false);
}
if (!m_vhtSupported && GetRifsSupported () && htOperation.GetRifsMode ())
{
m_stationManager->SetRifsPermitted (true);
}
else
{
m_stationManager->SetRifsPermitted (false);
}
}
}
if (m_vhtSupported)

View File

@@ -189,7 +189,7 @@ WifiMac::GetTypeId (void)
MakeTimeAccessor (&WifiMac::SetPifs,
&WifiMac::GetPifs),
MakeTimeChecker ())
.AddAttribute ("Rifs", "The value of the RIFS constant (not supported yet!).",
.AddAttribute ("Rifs", "The value of the RIFS constant.",
TimeValue (GetDefaultRifs ()),
MakeTimeAccessor (&WifiMac::SetRifs,
&WifiMac::GetRifs),

View File

@@ -158,6 +158,10 @@ public:
* \return whether the device supports short slot time capability.
*/
virtual bool GetShortSlotTimeSupported (void) const = 0;
/**
* \return whether the device supports RIFS capability.
*/
virtual bool GetRifsSupported (void) const = 0;
/**
* \param packet the packet to send.

View File

@@ -360,7 +360,8 @@ WifiRemoteStationManager::WifiRemoteStationManager ()
m_useNonErpProtection (false),
m_useGreenfieldProtection (false),
m_shortPreambleEnabled (false),
m_shortSlotTimeEnabled (false)
m_shortSlotTimeEnabled (false),
m_rifsPermitted (false)
{
}
@@ -463,6 +464,12 @@ WifiRemoteStationManager::SetShortSlotTimeEnabled (bool enable)
m_shortSlotTimeEnabled = enable;
}
void
WifiRemoteStationManager::SetRifsPermitted (bool allow)
{
m_rifsPermitted = allow;
}
bool
WifiRemoteStationManager::GetShortSlotTimeEnabled (void) const
{
@@ -475,6 +482,12 @@ WifiRemoteStationManager::GetShortPreambleEnabled (void) const
return m_shortPreambleEnabled;
}
bool
WifiRemoteStationManager::GetRifsPermitted (void) const
{
return m_rifsPermitted;
}
WifiRemoteStationManager::ProtectionMode
WifiRemoteStationManager::GetProtectionMode (void) const
{

View File

@@ -305,6 +305,19 @@ public:
* false otherwise
*/
bool GetShortSlotTimeEnabled (void) const;
/**
* Permit or prohibit RIFS.
*
* \param allow permit or prohibit RIFS
*/
void SetRifsPermitted (bool allow);
/**
* Return whether the device can use RIFS.
*
* \return true if RIFS is permitted,
* false otherwise
*/
bool GetRifsPermitted (void) const;
/**
* Reset the station, invoked in a STA upon dis-association or in an AP upon reboot.
@@ -1362,6 +1375,7 @@ private:
bool m_useGreenfieldProtection; //!< flag if protection for stations that do not support HT greenfield format is enabled
bool m_shortPreambleEnabled; //!< flag if short PLCP preamble is enabled
bool m_shortSlotTimeEnabled; //!< flag if short slot time is enabled
bool m_rifsPermitted; //!< flag if RIFS is enabled
ProtectionMode m_protectionMode; //!< Protection mode for ERP stations when non-ERP stations are detected
/**