wifi: Fix EIFS computation
EIFS depends on the modulation class of the PPDU whose reception failed rather than on the latest standard supported by a device
This commit is contained in:
@@ -42,6 +42,7 @@ The required Doxygen version for documentation generation is now version 1.13.
|
||||
- (wifi) #2368 - Fix various issues related to Content Channels and RU allocation. Fixes mostly covers cases where OFDMA is used with central 26 tones, where a single user is being assigned the whole PPDU bandwidth or where a RU is larger than 20 MHz.
|
||||
- (zigbee) !2383 - Fix malformed RREP command with missing command options field.
|
||||
- (wifi) Fix the time the `NSlotsLeftAlert` trace source of `ChannelAccessManager` is fired (it cannot be earlier than the access grant start time)
|
||||
- (wifi) Fix the EIFS computation, which depends on the modulation class of the PPDU whose reception failed rather than on the latest standard supported by a device
|
||||
|
||||
## Release 3.44
|
||||
|
||||
|
||||
@@ -90,11 +90,11 @@ class PhyListener : public ns3::WifiPhyListener
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyRxEndError() override
|
||||
void NotifyRxEndError(const WifiTxVector& txVector) override
|
||||
{
|
||||
if (m_active)
|
||||
{
|
||||
m_cam->NotifyRxEndErrorNow();
|
||||
m_cam->NotifyRxEndErrorNow(txVector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -985,14 +985,14 @@ ChannelAccessManager::NotifyRxEndOkNow()
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::NotifyRxEndErrorNow()
|
||||
ChannelAccessManager::NotifyRxEndErrorNow(const WifiTxVector& txVector)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
NS_LOG_DEBUG("rx end error");
|
||||
// we expect the PHY to notify us of the start of a CCA busy period, if needed
|
||||
m_lastRx.end = Simulator::Now();
|
||||
m_lastRxReceivedOk = false;
|
||||
m_eifsNoDifs = m_phy->GetSifs() + m_phy->GetAckTxTime();
|
||||
m_eifsNoDifs = m_phy->GetSifs() + GetEstimatedAckTxTime(txVector);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -33,6 +33,7 @@ class WifiPhy;
|
||||
class PhyListener;
|
||||
class Txop;
|
||||
class FrameExchangeManager;
|
||||
class WifiTxVector;
|
||||
enum AcIndex : uint8_t; // opaque enum declaration
|
||||
|
||||
/**
|
||||
@@ -236,8 +237,10 @@ class ChannelAccessManager : public Object
|
||||
/**
|
||||
* Notify the Txop that a packet reception was just
|
||||
* completed unsuccessfuly.
|
||||
*
|
||||
* @param txVector the TXVECTOR used for transmission
|
||||
*/
|
||||
void NotifyRxEndErrorNow();
|
||||
void NotifyRxEndErrorNow(const WifiTxVector& txVector);
|
||||
/**
|
||||
* @param duration expected duration of transmission
|
||||
*
|
||||
|
||||
@@ -63,7 +63,7 @@ class EmlsrPhyListener : public WifiPhyListener
|
||||
m_emlsrManager);
|
||||
}
|
||||
|
||||
void NotifyRxEndError() override
|
||||
void NotifyRxEndError(const WifiTxVector& /* txVector */) override
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -873,7 +873,7 @@ HePhy::RxPayloadFailed(Ptr<const WifiPsdu> psdu, double snr, const WifiTxVector&
|
||||
NS_LOG_FUNCTION(this << *psdu << txVector << snr);
|
||||
if (!txVector.IsUlMu())
|
||||
{
|
||||
m_state->SwitchFromRxEndError();
|
||||
m_state->SwitchFromRxEndError(txVector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -906,7 +906,7 @@ HePhy::DoEndReceivePayload(Ptr<const WifiPpdu> ppdu)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state->SwitchFromRxEndError();
|
||||
m_state->SwitchFromRxEndError(ppdu->GetTxVector());
|
||||
}
|
||||
NotifyInterferenceRxEndAndClear(true); // reset WifiPhy
|
||||
m_rxHeTbPpdus = 0;
|
||||
|
||||
@@ -785,7 +785,7 @@ void
|
||||
PhyEntity::RxPayloadFailed(Ptr<const WifiPsdu> psdu, double snr, const WifiTxVector& txVector)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *psdu << txVector << snr);
|
||||
m_state->SwitchFromRxEndError();
|
||||
m_state->SwitchFromRxEndError(txVector);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
class WifiTxVector;
|
||||
|
||||
/**
|
||||
* @brief receive notifications about PHY events.
|
||||
*/
|
||||
@@ -51,11 +53,13 @@ class WifiPhyListener
|
||||
*/
|
||||
virtual void NotifyRxEndOk() = 0;
|
||||
/**
|
||||
* @param txVector the TXVECTOR used for transmission
|
||||
*
|
||||
* We have received the last bit of a packet for which
|
||||
* NotifyRxStart was invoked first and, the packet has
|
||||
* _not_ been successfully received.
|
||||
*/
|
||||
virtual void NotifyRxEndError() = 0;
|
||||
virtual void NotifyRxEndError(const WifiTxVector& txVector) = 0;
|
||||
/**
|
||||
* @param duration the expected transmission duration.
|
||||
* @param txPower the nominal TX power
|
||||
|
||||
@@ -482,11 +482,11 @@ WifiPhyStateHelper::SwitchFromRxEndOk()
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhyStateHelper::SwitchFromRxEndError()
|
||||
WifiPhyStateHelper::SwitchFromRxEndError(const WifiTxVector& txVector)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
NS_ASSERT(m_endRx == Simulator::Now());
|
||||
NotifyListeners(&WifiPhyListener::NotifyRxEndError);
|
||||
NotifyListeners(&WifiPhyListener::NotifyRxEndError, txVector);
|
||||
DoSwitchFromRx();
|
||||
}
|
||||
|
||||
|
||||
@@ -246,8 +246,10 @@ class WifiPhyStateHelper : public Object
|
||||
void SwitchFromRxEndOk();
|
||||
/**
|
||||
* Switch from RX after the reception failed.
|
||||
*
|
||||
* @param txVector the TXVECTOR used for transmission of failed frame
|
||||
*/
|
||||
void SwitchFromRxEndError();
|
||||
void SwitchFromRxEndError(const WifiTxVector& txVector);
|
||||
/**
|
||||
* Abort current reception following a CCA reset request.
|
||||
* @param operatingWidth the channel width the PHY is operating on
|
||||
|
||||
@@ -514,7 +514,7 @@ WifiRadioEnergyModelPhyListener::NotifyRxEndOk()
|
||||
}
|
||||
|
||||
void
|
||||
WifiRadioEnergyModelPhyListener::NotifyRxEndError()
|
||||
WifiRadioEnergyModelPhyListener::NotifyRxEndError(const WifiTxVector& /* txVector */)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
if (m_changeStateCallback.IsNull())
|
||||
|
||||
@@ -56,7 +56,7 @@ class WifiRadioEnergyModelPhyListener : public WifiPhyListener
|
||||
|
||||
void NotifyRxStart(Time duration) override;
|
||||
void NotifyRxEndOk() override;
|
||||
void NotifyRxEndError() override;
|
||||
void NotifyRxEndError(const WifiTxVector& txVector) override;
|
||||
void NotifyTxStart(Time duration, dBm_u txPower) override;
|
||||
void NotifyCcaBusyStart(Time duration,
|
||||
WifiChannelListType channelType,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "gcr-manager.h"
|
||||
#include "wifi-mac-header.h"
|
||||
#include "wifi-mac-trailer.h"
|
||||
#include "wifi-tx-vector.h"
|
||||
|
||||
#include "ns3/packet.h"
|
||||
|
||||
@@ -109,6 +110,61 @@ GetCtsSize()
|
||||
return size;
|
||||
}
|
||||
|
||||
Time
|
||||
GetEstimatedAckTxTime(const WifiTxVector& txVector)
|
||||
{
|
||||
auto modClass = txVector.GetModulationClass();
|
||||
|
||||
switch (modClass)
|
||||
{
|
||||
case WIFI_MOD_CLASS_DSSS:
|
||||
case WIFI_MOD_CLASS_HR_DSSS:
|
||||
if (txVector.GetMode().GetDataRate(txVector) == 1e6)
|
||||
{
|
||||
return MicroSeconds(304);
|
||||
}
|
||||
else if (txVector.GetPreambleType() == WIFI_PREAMBLE_LONG)
|
||||
{
|
||||
return MicroSeconds(248);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MicroSeconds(152);
|
||||
}
|
||||
break;
|
||||
case WIFI_MOD_CLASS_ERP_OFDM:
|
||||
case WIFI_MOD_CLASS_OFDM:
|
||||
if (auto constSize = txVector.GetMode().GetConstellationSize(); constSize == 2)
|
||||
{
|
||||
return MicroSeconds(44);
|
||||
}
|
||||
else if (constSize == 4)
|
||||
{
|
||||
return MicroSeconds(32);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MicroSeconds(28);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
auto staId = (txVector.IsMu() ? txVector.GetHeMuUserInfoMap().begin()->first : SU_STA_ID);
|
||||
if (const auto constSize = txVector.GetMode(staId).GetConstellationSize(); constSize == 2)
|
||||
{
|
||||
return MicroSeconds(68);
|
||||
}
|
||||
else if (constSize == 4)
|
||||
{
|
||||
return MicroSeconds(44);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MicroSeconds(32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ class Mac48Address;
|
||||
class WifiMacHeader;
|
||||
class Packet;
|
||||
class WifiMac;
|
||||
class WifiTxVector;
|
||||
|
||||
/**
|
||||
* Wifi direction. Values are those defined for the TID-to-Link Mapping Control Direction
|
||||
@@ -195,6 +196,13 @@ uint32_t GetRtsSize();
|
||||
* @return the total CTS size in bytes
|
||||
*/
|
||||
uint32_t GetCtsSize();
|
||||
|
||||
/**
|
||||
* @param txVector the TXVECTOR used to transmit a frame whose reception failed
|
||||
* @return the estimated Ack TX time, based on Table 10-8 of IEEE 802.11REVme D7.0
|
||||
*/
|
||||
Time GetEstimatedAckTxTime(const WifiTxVector& txVector);
|
||||
|
||||
/**
|
||||
* @param seq MPDU sequence number
|
||||
* @param winstart sequence number window start
|
||||
|
||||
@@ -732,7 +732,21 @@ ChannelAccessManagerTest<TxopType>::AddRxErrorEvt(uint64_t at, uint64_t duration
|
||||
MicroSeconds(duration));
|
||||
Simulator::Schedule(MicroSeconds(at + duration) - Now(),
|
||||
&ChannelAccessManager::NotifyRxEndErrorNow,
|
||||
m_ChannelAccessManager);
|
||||
m_ChannelAccessManager,
|
||||
WifiTxVector(OfdmPhy::GetOfdmRate6Mbps(),
|
||||
1,
|
||||
WIFI_PREAMBLE_LONG,
|
||||
NanoSeconds(800),
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
MHz_u{20},
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
false));
|
||||
}
|
||||
|
||||
template <typename TxopType>
|
||||
@@ -747,7 +761,21 @@ ChannelAccessManagerTest<TxopType>::AddRxErrorEvt(uint64_t at,
|
||||
MicroSeconds(duration));
|
||||
Simulator::Schedule(MicroSeconds(at + timeUntilError) - Now(),
|
||||
&ChannelAccessManager::NotifyRxEndErrorNow,
|
||||
m_ChannelAccessManager);
|
||||
m_ChannelAccessManager,
|
||||
WifiTxVector(OfdmPhy::GetOfdmRate6Mbps(),
|
||||
1,
|
||||
WIFI_PREAMBLE_LONG,
|
||||
NanoSeconds(800),
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
MHz_u{20},
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
false));
|
||||
Simulator::Schedule(MicroSeconds(at + timeUntilError) - Now(),
|
||||
&ChannelAccessManager::NotifyCcaBusyStartNow,
|
||||
m_ChannelAccessManager,
|
||||
|
||||
@@ -327,9 +327,9 @@ class TestPhyListener : public ns3::WifiPhyListener
|
||||
++m_notifyRxEndOk;
|
||||
}
|
||||
|
||||
void NotifyRxEndError() override
|
||||
void NotifyRxEndError(const WifiTxVector& txVector) override
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
NS_LOG_FUNCTION(this << txVector);
|
||||
++m_notifyRxEndError;
|
||||
}
|
||||
|
||||
|
||||
@@ -627,9 +627,9 @@ class CcaTestPhyListener : public ns3::WifiPhyListener
|
||||
NS_LOG_FUNCTION(this);
|
||||
}
|
||||
|
||||
void NotifyRxEndError() override
|
||||
void NotifyRxEndError(const WifiTxVector& txVector) override
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
NS_LOG_FUNCTION(this << txVector);
|
||||
}
|
||||
|
||||
void NotifyTxStart(Time duration, dBm_u txPower) override
|
||||
|
||||
@@ -2890,9 +2890,9 @@ class OfdmaTestPhyListener : public ns3::WifiPhyListener
|
||||
m_lastRxSuccess = true;
|
||||
}
|
||||
|
||||
void NotifyRxEndError() override
|
||||
void NotifyRxEndError(const WifiTxVector& txVector) override
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
NS_LOG_FUNCTION(this << txVector);
|
||||
m_lastRxEnd = Simulator::Now();
|
||||
++m_notifyRxEnd;
|
||||
m_lastRxSuccess = false;
|
||||
|
||||
Reference in New Issue
Block a user