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.
|
- (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.
|
- (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 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
|
## Release 3.44
|
||||||
|
|
||||||
|
|||||||
@@ -90,11 +90,11 @@ class PhyListener : public ns3::WifiPhyListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyRxEndError() override
|
void NotifyRxEndError(const WifiTxVector& txVector) override
|
||||||
{
|
{
|
||||||
if (m_active)
|
if (m_active)
|
||||||
{
|
{
|
||||||
m_cam->NotifyRxEndErrorNow();
|
m_cam->NotifyRxEndErrorNow(txVector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -985,14 +985,14 @@ ChannelAccessManager::NotifyRxEndOkNow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ChannelAccessManager::NotifyRxEndErrorNow()
|
ChannelAccessManager::NotifyRxEndErrorNow(const WifiTxVector& txVector)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION(this);
|
NS_LOG_FUNCTION(this);
|
||||||
NS_LOG_DEBUG("rx end error");
|
NS_LOG_DEBUG("rx end error");
|
||||||
// we expect the PHY to notify us of the start of a CCA busy period, if needed
|
// we expect the PHY to notify us of the start of a CCA busy period, if needed
|
||||||
m_lastRx.end = Simulator::Now();
|
m_lastRx.end = Simulator::Now();
|
||||||
m_lastRxReceivedOk = false;
|
m_lastRxReceivedOk = false;
|
||||||
m_eifsNoDifs = m_phy->GetSifs() + m_phy->GetAckTxTime();
|
m_eifsNoDifs = m_phy->GetSifs() + GetEstimatedAckTxTime(txVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class WifiPhy;
|
|||||||
class PhyListener;
|
class PhyListener;
|
||||||
class Txop;
|
class Txop;
|
||||||
class FrameExchangeManager;
|
class FrameExchangeManager;
|
||||||
|
class WifiTxVector;
|
||||||
enum AcIndex : uint8_t; // opaque enum declaration
|
enum AcIndex : uint8_t; // opaque enum declaration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,8 +237,10 @@ class ChannelAccessManager : public Object
|
|||||||
/**
|
/**
|
||||||
* Notify the Txop that a packet reception was just
|
* Notify the Txop that a packet reception was just
|
||||||
* completed unsuccessfuly.
|
* completed unsuccessfuly.
|
||||||
|
*
|
||||||
|
* @param txVector the TXVECTOR used for transmission
|
||||||
*/
|
*/
|
||||||
void NotifyRxEndErrorNow();
|
void NotifyRxEndErrorNow(const WifiTxVector& txVector);
|
||||||
/**
|
/**
|
||||||
* @param duration expected duration of transmission
|
* @param duration expected duration of transmission
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class EmlsrPhyListener : public WifiPhyListener
|
|||||||
m_emlsrManager);
|
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);
|
NS_LOG_FUNCTION(this << *psdu << txVector << snr);
|
||||||
if (!txVector.IsUlMu())
|
if (!txVector.IsUlMu())
|
||||||
{
|
{
|
||||||
m_state->SwitchFromRxEndError();
|
m_state->SwitchFromRxEndError(txVector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,7 +906,7 @@ HePhy::DoEndReceivePayload(Ptr<const WifiPpdu> ppdu)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_state->SwitchFromRxEndError();
|
m_state->SwitchFromRxEndError(ppdu->GetTxVector());
|
||||||
}
|
}
|
||||||
NotifyInterferenceRxEndAndClear(true); // reset WifiPhy
|
NotifyInterferenceRxEndAndClear(true); // reset WifiPhy
|
||||||
m_rxHeTbPpdus = 0;
|
m_rxHeTbPpdus = 0;
|
||||||
|
|||||||
@@ -785,7 +785,7 @@ void
|
|||||||
PhyEntity::RxPayloadFailed(Ptr<const WifiPsdu> psdu, double snr, const WifiTxVector& txVector)
|
PhyEntity::RxPayloadFailed(Ptr<const WifiPsdu> psdu, double snr, const WifiTxVector& txVector)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION(this << *psdu << txVector << snr);
|
NS_LOG_FUNCTION(this << *psdu << txVector << snr);
|
||||||
m_state->SwitchFromRxEndError();
|
m_state->SwitchFromRxEndError(txVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
namespace ns3
|
namespace ns3
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class WifiTxVector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief receive notifications about PHY events.
|
* @brief receive notifications about PHY events.
|
||||||
*/
|
*/
|
||||||
@@ -51,11 +53,13 @@ class WifiPhyListener
|
|||||||
*/
|
*/
|
||||||
virtual void NotifyRxEndOk() = 0;
|
virtual void NotifyRxEndOk() = 0;
|
||||||
/**
|
/**
|
||||||
|
* @param txVector the TXVECTOR used for transmission
|
||||||
|
*
|
||||||
* We have received the last bit of a packet for which
|
* We have received the last bit of a packet for which
|
||||||
* NotifyRxStart was invoked first and, the packet has
|
* NotifyRxStart was invoked first and, the packet has
|
||||||
* _not_ been successfully received.
|
* _not_ been successfully received.
|
||||||
*/
|
*/
|
||||||
virtual void NotifyRxEndError() = 0;
|
virtual void NotifyRxEndError(const WifiTxVector& txVector) = 0;
|
||||||
/**
|
/**
|
||||||
* @param duration the expected transmission duration.
|
* @param duration the expected transmission duration.
|
||||||
* @param txPower the nominal TX power
|
* @param txPower the nominal TX power
|
||||||
|
|||||||
@@ -482,11 +482,11 @@ WifiPhyStateHelper::SwitchFromRxEndOk()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WifiPhyStateHelper::SwitchFromRxEndError()
|
WifiPhyStateHelper::SwitchFromRxEndError(const WifiTxVector& txVector)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION(this);
|
NS_LOG_FUNCTION(this);
|
||||||
NS_ASSERT(m_endRx == Simulator::Now());
|
NS_ASSERT(m_endRx == Simulator::Now());
|
||||||
NotifyListeners(&WifiPhyListener::NotifyRxEndError);
|
NotifyListeners(&WifiPhyListener::NotifyRxEndError, txVector);
|
||||||
DoSwitchFromRx();
|
DoSwitchFromRx();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,8 +246,10 @@ class WifiPhyStateHelper : public Object
|
|||||||
void SwitchFromRxEndOk();
|
void SwitchFromRxEndOk();
|
||||||
/**
|
/**
|
||||||
* Switch from RX after the reception failed.
|
* 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.
|
* Abort current reception following a CCA reset request.
|
||||||
* @param operatingWidth the channel width the PHY is operating on
|
* @param operatingWidth the channel width the PHY is operating on
|
||||||
|
|||||||
@@ -514,7 +514,7 @@ WifiRadioEnergyModelPhyListener::NotifyRxEndOk()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WifiRadioEnergyModelPhyListener::NotifyRxEndError()
|
WifiRadioEnergyModelPhyListener::NotifyRxEndError(const WifiTxVector& /* txVector */)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION(this);
|
NS_LOG_FUNCTION(this);
|
||||||
if (m_changeStateCallback.IsNull())
|
if (m_changeStateCallback.IsNull())
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class WifiRadioEnergyModelPhyListener : public WifiPhyListener
|
|||||||
|
|
||||||
void NotifyRxStart(Time duration) override;
|
void NotifyRxStart(Time duration) override;
|
||||||
void NotifyRxEndOk() override;
|
void NotifyRxEndOk() override;
|
||||||
void NotifyRxEndError() override;
|
void NotifyRxEndError(const WifiTxVector& txVector) override;
|
||||||
void NotifyTxStart(Time duration, dBm_u txPower) override;
|
void NotifyTxStart(Time duration, dBm_u txPower) override;
|
||||||
void NotifyCcaBusyStart(Time duration,
|
void NotifyCcaBusyStart(Time duration,
|
||||||
WifiChannelListType channelType,
|
WifiChannelListType channelType,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "gcr-manager.h"
|
#include "gcr-manager.h"
|
||||||
#include "wifi-mac-header.h"
|
#include "wifi-mac-header.h"
|
||||||
#include "wifi-mac-trailer.h"
|
#include "wifi-mac-trailer.h"
|
||||||
|
#include "wifi-tx-vector.h"
|
||||||
|
|
||||||
#include "ns3/packet.h"
|
#include "ns3/packet.h"
|
||||||
|
|
||||||
@@ -109,6 +110,61 @@ GetCtsSize()
|
|||||||
return size;
|
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
|
bool
|
||||||
IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
|
IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class Mac48Address;
|
|||||||
class WifiMacHeader;
|
class WifiMacHeader;
|
||||||
class Packet;
|
class Packet;
|
||||||
class WifiMac;
|
class WifiMac;
|
||||||
|
class WifiTxVector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wifi direction. Values are those defined for the TID-to-Link Mapping Control Direction
|
* 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
|
* @return the total CTS size in bytes
|
||||||
*/
|
*/
|
||||||
uint32_t GetCtsSize();
|
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 seq MPDU sequence number
|
||||||
* @param winstart sequence number window start
|
* @param winstart sequence number window start
|
||||||
|
|||||||
@@ -732,7 +732,21 @@ ChannelAccessManagerTest<TxopType>::AddRxErrorEvt(uint64_t at, uint64_t duration
|
|||||||
MicroSeconds(duration));
|
MicroSeconds(duration));
|
||||||
Simulator::Schedule(MicroSeconds(at + duration) - Now(),
|
Simulator::Schedule(MicroSeconds(at + duration) - Now(),
|
||||||
&ChannelAccessManager::NotifyRxEndErrorNow,
|
&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>
|
template <typename TxopType>
|
||||||
@@ -747,7 +761,21 @@ ChannelAccessManagerTest<TxopType>::AddRxErrorEvt(uint64_t at,
|
|||||||
MicroSeconds(duration));
|
MicroSeconds(duration));
|
||||||
Simulator::Schedule(MicroSeconds(at + timeUntilError) - Now(),
|
Simulator::Schedule(MicroSeconds(at + timeUntilError) - Now(),
|
||||||
&ChannelAccessManager::NotifyRxEndErrorNow,
|
&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(),
|
Simulator::Schedule(MicroSeconds(at + timeUntilError) - Now(),
|
||||||
&ChannelAccessManager::NotifyCcaBusyStartNow,
|
&ChannelAccessManager::NotifyCcaBusyStartNow,
|
||||||
m_ChannelAccessManager,
|
m_ChannelAccessManager,
|
||||||
|
|||||||
@@ -327,9 +327,9 @@ class TestPhyListener : public ns3::WifiPhyListener
|
|||||||
++m_notifyRxEndOk;
|
++m_notifyRxEndOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyRxEndError() override
|
void NotifyRxEndError(const WifiTxVector& txVector) override
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION(this);
|
NS_LOG_FUNCTION(this << txVector);
|
||||||
++m_notifyRxEndError;
|
++m_notifyRxEndError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -627,9 +627,9 @@ class CcaTestPhyListener : public ns3::WifiPhyListener
|
|||||||
NS_LOG_FUNCTION(this);
|
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
|
void NotifyTxStart(Time duration, dBm_u txPower) override
|
||||||
|
|||||||
@@ -2890,9 +2890,9 @@ class OfdmaTestPhyListener : public ns3::WifiPhyListener
|
|||||||
m_lastRxSuccess = true;
|
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_lastRxEnd = Simulator::Now();
|
||||||
++m_notifyRxEnd;
|
++m_notifyRxEnd;
|
||||||
m_lastRxSuccess = false;
|
m_lastRxSuccess = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user