wifi: (fixes #2528) Improve 802.11n RIFS support
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user