wifi: Rework InterferenceHelper to handle calculations per [band start index; band stop index] pair
This commit is contained in:
committed by
Sébastien Deronne
parent
4e51fc0b9a
commit
7d7bf0e0f8
@@ -197,10 +197,10 @@ WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity (uint32_t centerFreque
|
||||
uint32_t stop2 = start2 + 26 - 1;
|
||||
|
||||
//Build transmit spectrum mask
|
||||
std::vector <StartStop> subBands;
|
||||
std::vector <WifiSpectrumBand> subBands;
|
||||
subBands.push_back (std::make_pair (start1, stop1));
|
||||
subBands.push_back (std::make_pair (start2, stop2));
|
||||
StartStop maskBand (0, nAllocatedBands + nGuardBands);
|
||||
WifiSpectrumBand maskBand (0, nAllocatedBands + nGuardBands);
|
||||
CreateSpectrumMaskForOfdm (c, subBands, maskBand,
|
||||
txPowerPerBandW, nGuardBands,
|
||||
innerSlopeWidth, -40.0); // -40 dBr for the outermost points of the standard defined mask for 11a, 11g and downclocked versions of 11a for 11p
|
||||
@@ -260,8 +260,8 @@ WifiSpectrumValueHelper::CreateHtOfdmTxPowerSpectralDensity (uint32_t centerFreq
|
||||
double lowestPointDbr = (centerFrequency >= 5000) ?
|
||||
-40.0 : //if 5 GHz band
|
||||
-45.0; //if 2.4 GHz band
|
||||
std::vector <StartStop> subBands; //list of data/pilot-containing subBands (sent at 0dBr)
|
||||
StartStop maskBand (0, nAllocatedBands + nGuardBands);
|
||||
std::vector <WifiSpectrumBand> subBands; //list of data/pilot-containing subBands (sent at 0dBr)
|
||||
WifiSpectrumBand maskBand (0, nAllocatedBands + nGuardBands);
|
||||
switch (channelWidth)
|
||||
{
|
||||
case 20:
|
||||
@@ -349,8 +349,8 @@ WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (uint32_t centerFreq
|
||||
double lowestPointDbr = (centerFrequency >= 5000) ?
|
||||
-40.0 : //if 5 GHz band
|
||||
-45.0; //if 2.4 GHz band
|
||||
std::vector <StartStop> subBands; //list of data/pilot-containing subBands (sent at 0dBr)
|
||||
StartStop maskBand (0, nAllocatedBands + nGuardBands);
|
||||
std::vector <WifiSpectrumBand> subBands; //list of data/pilot-containing subBands (sent at 0dBr)
|
||||
WifiSpectrumBand maskBand (0, nAllocatedBands + nGuardBands);
|
||||
switch (channelWidth)
|
||||
{
|
||||
case 20:
|
||||
@@ -449,34 +449,26 @@ WifiSpectrumValueHelper::CreateNoisePowerSpectralDensity (double noiseFigureDb,
|
||||
}
|
||||
|
||||
Ptr<SpectrumValue>
|
||||
WifiSpectrumValueHelper::CreateRfFilter (uint32_t centerFrequency, uint16_t channelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth)
|
||||
WifiSpectrumValueHelper::CreateRfFilter (uint32_t centerFrequency, uint16_t totalChannelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth, WifiSpectrumBand band)
|
||||
{
|
||||
NS_LOG_FUNCTION (centerFrequency << channelWidth << bandBandwidth << guardBandwidth);
|
||||
Ptr<SpectrumValue> c = Create <SpectrumValue> (GetSpectrumModel (centerFrequency, channelWidth, bandBandwidth, guardBandwidth));
|
||||
size_t numBands = c->GetSpectrumModel ()->GetNumBands ();
|
||||
uint32_t startIndex = band.first;
|
||||
uint32_t stopIndex = band.second;
|
||||
NS_LOG_FUNCTION (centerFrequency << totalChannelWidth << bandBandwidth << guardBandwidth << startIndex << stopIndex);
|
||||
Ptr<SpectrumValue> c = Create <SpectrumValue> (GetSpectrumModel (centerFrequency, totalChannelWidth, bandBandwidth, guardBandwidth));
|
||||
Bands::const_iterator bit = c->ConstBandsBegin ();
|
||||
Values::iterator vit = c->ValuesBegin ();
|
||||
size_t numBandsInFilter = static_cast<size_t> (channelWidth * 1e6 / bandBandwidth);
|
||||
if (channelWidth % bandBandwidth != 0)
|
||||
{
|
||||
numBandsInFilter += 1;
|
||||
}
|
||||
NS_LOG_INFO ("Num bands in filter: " << numBandsInFilter);
|
||||
// Set the value of the filter to 1 for the center-most numBandsInFilter
|
||||
NS_ASSERT_MSG ((numBandsInFilter % 2 == 1) && (numBands % 2 == 1), "Should have odd number of bands");
|
||||
size_t startIndex = (numBands - numBandsInFilter) / 2;
|
||||
vit += startIndex;
|
||||
bit += startIndex;
|
||||
for (size_t i = startIndex; i < startIndex + numBandsInFilter; i++, vit++, bit++)
|
||||
for (size_t i = startIndex; i <= stopIndex; i++, vit++, bit++)
|
||||
{
|
||||
*vit = 1;
|
||||
}
|
||||
NS_LOG_LOGIC ("Added subbands " << startIndex << " to " << startIndex + numBandsInFilter << " to filter");
|
||||
NS_LOG_LOGIC ("Added subbands " << startIndex << " to " << stopIndex << " to filter");
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
WifiSpectrumValueHelper::CreateSpectrumMaskForOfdm (Ptr<SpectrumValue> c, std::vector <StartStop> allocatedSubBands, StartStop maskBand,
|
||||
WifiSpectrumValueHelper::CreateSpectrumMaskForOfdm (Ptr<SpectrumValue> c, std::vector <WifiSpectrumBand> allocatedSubBands, WifiSpectrumBand maskBand,
|
||||
double txPowerPerBandW, uint32_t nGuardBands,
|
||||
uint32_t innerSlopeWidth, double lowestPointDbr)
|
||||
{
|
||||
@@ -496,22 +488,22 @@ WifiSpectrumValueHelper::CreateSpectrumMaskForOfdm (Ptr<SpectrumValue> c, std::v
|
||||
//Different widths (in number of bands)
|
||||
uint32_t outerSlopeWidth = nGuardBands / 4; // nGuardBands is the total left+right guard band. The left/right outer part is half of the left/right guard band.
|
||||
uint32_t middleSlopeWidth = outerSlopeWidth - (innerSlopeWidth / 2);
|
||||
StartStop outerBandLeft (maskBand.first, //to handle cases where allocated channel is under WifiPhy configured channel width.
|
||||
maskBand.first + outerSlopeWidth - 1);
|
||||
StartStop middleBandLeft (outerBandLeft.second + 1,
|
||||
outerBandLeft.second + middleSlopeWidth);
|
||||
StartStop innerBandLeft (allocatedSubBands.front ().first - innerSlopeWidth,
|
||||
allocatedSubBands.front ().first - 1); //better to place slope based on allocated subcarriers
|
||||
StartStop flatJunctionLeft (middleBandLeft.second + 1,
|
||||
innerBandLeft.first - 1); //in order to handle shift due to guard subcarriers
|
||||
StartStop outerBandRight (maskBand.second - outerSlopeWidth + 1,
|
||||
maskBand.second); //start from outer edge to be able to compute flat junction width
|
||||
StartStop middleBandRight (outerBandRight.first - middleSlopeWidth,
|
||||
outerBandRight.first - 1);
|
||||
StartStop innerBandRight (allocatedSubBands.back ().second + 1,
|
||||
allocatedSubBands.back ().second + innerSlopeWidth);
|
||||
StartStop flatJunctionRight (innerBandRight.second + 1,
|
||||
middleBandRight.first - 1);
|
||||
WifiSpectrumBand outerBandLeft (maskBand.first, //to handle cases where allocated channel is under WifiPhy configured channel width.
|
||||
maskBand.first + outerSlopeWidth - 1);
|
||||
WifiSpectrumBand middleBandLeft (outerBandLeft.second + 1,
|
||||
outerBandLeft.second + middleSlopeWidth);
|
||||
WifiSpectrumBand innerBandLeft (allocatedSubBands.front ().first - innerSlopeWidth,
|
||||
allocatedSubBands.front ().first - 1); //better to place slope based on allocated subcarriers
|
||||
WifiSpectrumBand flatJunctionLeft (middleBandLeft.second + 1,
|
||||
innerBandLeft.first - 1); //in order to handle shift due to guard subcarriers
|
||||
WifiSpectrumBand outerBandRight (maskBand.second - outerSlopeWidth + 1,
|
||||
maskBand.second); //start from outer edge to be able to compute flat junction width
|
||||
WifiSpectrumBand middleBandRight (outerBandRight.first - middleSlopeWidth,
|
||||
outerBandRight.first - 1);
|
||||
WifiSpectrumBand innerBandRight (allocatedSubBands.back ().second + 1,
|
||||
allocatedSubBands.back ().second + innerSlopeWidth);
|
||||
WifiSpectrumBand flatJunctionRight (innerBandRight.second + 1,
|
||||
middleBandRight.first - 1);
|
||||
NS_LOG_DEBUG ("outerBandLeft=[" << outerBandLeft.first << ";" << outerBandLeft.second << "] " <<
|
||||
"middleBandLeft=[" << middleBandLeft.first << ";" << middleBandLeft.second << "] " <<
|
||||
"flatJunctionLeft=[" << flatJunctionLeft.first << ";" << flatJunctionLeft.second << "] " <<
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* typedef for a pair of start and stop sub-band indexes
|
||||
*/
|
||||
typedef std::pair<uint32_t, uint32_t> WifiSpectrumBand;
|
||||
|
||||
/**
|
||||
* \ingroup spectrum
|
||||
*
|
||||
@@ -137,20 +142,16 @@ public:
|
||||
/**
|
||||
* Create a spectral density corresponding to the RF filter
|
||||
*
|
||||
* \param centerFrequency center frequency (MHz)
|
||||
* \param channelWidth channel width (MHz)
|
||||
* \param bandBandwidth width of each band (Hz)
|
||||
* \param guardBandwidth width of the guard band (MHz)
|
||||
* \param centerFrequency the center frequency (MHz)
|
||||
* \param totalChannelWidth the total channel width (MHz)
|
||||
* \param bandBandwidth the width of each band (MHz)
|
||||
* \param guardBandwidth the width of the guard band (MHz)
|
||||
* \param band the pair of start and stop indexes that defines the band to be filtered
|
||||
*
|
||||
* \return a pointer to a SpectrumValue representing the RF filter applied
|
||||
* to an received power spectral density
|
||||
*/
|
||||
static Ptr<SpectrumValue> CreateRfFilter (uint32_t centerFrequency, uint16_t channelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth);
|
||||
|
||||
/**
|
||||
* typedef for a pair of start and stop sub-band indexes
|
||||
*/
|
||||
typedef std::pair<uint32_t, uint32_t> StartStop;
|
||||
static Ptr<SpectrumValue> CreateRfFilter (uint32_t centerFrequency, uint16_t totalChannelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth, WifiSpectrumBand band);
|
||||
|
||||
/**
|
||||
* Create a transmit power spectral density corresponding to OFDM
|
||||
@@ -187,7 +188,7 @@ public:
|
||||
* \param lowestPointDbr maximum relative power of the outermost subcarriers of the guard band (in dBr)
|
||||
* \return a pointer to a newly allocated SpectrumValue representing the HT OFDM Transmit Power Spectral Density in W/Hz for each Band
|
||||
*/
|
||||
static void CreateSpectrumMaskForOfdm (Ptr<SpectrumValue> c, std::vector <StartStop> allocatedSubBands, StartStop maskBand,
|
||||
static void CreateSpectrumMaskForOfdm (Ptr<SpectrumValue> c, std::vector <WifiSpectrumBand> allocatedSubBands, WifiSpectrumBand maskBand,
|
||||
double txPowerPerBandW, uint32_t nGuardBands,
|
||||
uint32_t innerSlopeWidth, double lowestPointDbr);
|
||||
|
||||
|
||||
@@ -981,6 +981,9 @@ WifiHelper::EnableLogComponents (void)
|
||||
LogComponentEnable ("YansErrorRateModel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("YansWifiChannel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("YansWifiPhy", LOG_LEVEL_ALL);
|
||||
|
||||
//From Spectrum
|
||||
LogComponentEnable ("WifiSpectrumValueHelper", LOG_LEVEL_ALL);
|
||||
}
|
||||
|
||||
int64_t
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/packet.h"
|
||||
@@ -37,7 +39,7 @@ NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
|
||||
* PHY event class
|
||||
****************************************************************/
|
||||
|
||||
Event::Event (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, double rxPower)
|
||||
Event::Event (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, RxPowerWattPerChannelBand rxPower)
|
||||
: m_ppdu (ppdu),
|
||||
m_txVector (txVector),
|
||||
m_startTime (Simulator::Now ()),
|
||||
@@ -76,6 +78,26 @@ Event::GetDuration (void) const
|
||||
|
||||
double
|
||||
Event::GetRxPowerW (void) const
|
||||
{
|
||||
NS_ASSERT (m_rxPowerW.size () > 0);
|
||||
//The total RX power corresponds to the maximum over all the bands
|
||||
auto it = std::max_element (m_rxPowerW.begin (), m_rxPowerW.end (),
|
||||
[] (const std::pair<WifiSpectrumBand, double>& p1, const std::pair<WifiSpectrumBand, double>& p2) {
|
||||
return p1.second < p2.second;
|
||||
});
|
||||
return it->second;
|
||||
}
|
||||
|
||||
double
|
||||
Event::GetRxPowerW (WifiSpectrumBand band) const
|
||||
{
|
||||
auto it = m_rxPowerW.find (band);
|
||||
NS_ASSERT (it != m_rxPowerW.end ());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
RxPowerWattPerChannelBand
|
||||
Event::GetRxPowerWPerBand (void) const
|
||||
{
|
||||
return m_rxPowerW;
|
||||
}
|
||||
@@ -132,11 +154,8 @@ InterferenceHelper::NiChange::GetEvent (void) const
|
||||
InterferenceHelper::InterferenceHelper ()
|
||||
: m_errorRateModel (0),
|
||||
m_numRxAntennas (1),
|
||||
m_firstPower (0),
|
||||
m_rxing (false)
|
||||
{
|
||||
// Always have a zero power noise event in the list
|
||||
AddNiChangeEvent (Time (0), NiChange (0.0, 0));
|
||||
}
|
||||
|
||||
InterferenceHelper::~InterferenceHelper ()
|
||||
@@ -146,7 +165,7 @@ InterferenceHelper::~InterferenceHelper ()
|
||||
}
|
||||
|
||||
Ptr<Event>
|
||||
InterferenceHelper::Add (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, double rxPowerW)
|
||||
InterferenceHelper::Add (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, RxPowerWattPerChannelBand rxPowerW)
|
||||
{
|
||||
Ptr<Event> event = Create<Event> (ppdu, txVector, duration, rxPowerW);
|
||||
AppendEvent (event);
|
||||
@@ -154,7 +173,7 @@ InterferenceHelper::Add (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time d
|
||||
}
|
||||
|
||||
void
|
||||
InterferenceHelper::AddForeignSignal (Time duration, double rxPowerW)
|
||||
InterferenceHelper::AddForeignSignal (Time duration, RxPowerWattPerChannelBand rxPowerW)
|
||||
{
|
||||
// Parameters other than duration and rxPowerW are unused for this type
|
||||
// of signal, so we provide dummy versions
|
||||
@@ -165,6 +184,26 @@ InterferenceHelper::AddForeignSignal (Time duration, double rxPowerW)
|
||||
Add (fakePpdu, WifiTxVector (), duration, rxPowerW);
|
||||
}
|
||||
|
||||
void
|
||||
InterferenceHelper::RemoveBands(void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_niChangesPerBand.clear();
|
||||
m_firstPowerPerBand.clear();
|
||||
}
|
||||
|
||||
void
|
||||
InterferenceHelper::AddBand (WifiSpectrumBand band)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
NS_ASSERT (m_niChangesPerBand.find (band) == m_niChangesPerBand.end ());
|
||||
NiChanges niChanges;
|
||||
m_niChangesPerBand.insert ({band, niChanges});
|
||||
// Always have a zero power noise event in the list
|
||||
AddNiChangeEvent (Time (0), NiChange (0.0, 0), band);
|
||||
m_firstPowerPerBand.insert ({band, 0.0});
|
||||
}
|
||||
|
||||
void
|
||||
InterferenceHelper::SetNoiseFigure (double value)
|
||||
{
|
||||
@@ -190,12 +229,14 @@ InterferenceHelper::SetNumberOfReceiveAntennas (uint8_t rx)
|
||||
}
|
||||
|
||||
Time
|
||||
InterferenceHelper::GetEnergyDuration (double energyW) const
|
||||
InterferenceHelper::GetEnergyDuration (double energyW, WifiSpectrumBand band) const
|
||||
{
|
||||
Time now = Simulator::Now ();
|
||||
auto i = GetPreviousPosition (now);
|
||||
auto i = GetPreviousPosition (now, band);
|
||||
Time end = i->first;
|
||||
for (; i != m_niChanges.end (); ++i)
|
||||
auto ni_it = m_niChangesPerBand.find (band);
|
||||
NS_ASSERT (ni_it != m_niChangesPerBand.end ());
|
||||
for (; i != ni_it->second.end (); ++i)
|
||||
{
|
||||
double noiseInterferenceW = i->second.GetPower ();
|
||||
end = i->first;
|
||||
@@ -211,29 +252,35 @@ void
|
||||
InterferenceHelper::AppendEvent (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
double previousPowerStart = 0;
|
||||
double previousPowerEnd = 0;
|
||||
previousPowerStart = GetPreviousPosition (event->GetStartTime ())->second.GetPower ();
|
||||
previousPowerEnd = GetPreviousPosition (event->GetEndTime ())->second.GetPower ();
|
||||
|
||||
if (!m_rxing)
|
||||
RxPowerWattPerChannelBand rxPowerWattPerChannelBand = event->GetRxPowerWPerBand ();
|
||||
for (auto const& it : rxPowerWattPerChannelBand)
|
||||
{
|
||||
m_firstPower = previousPowerStart;
|
||||
// Always leave the first zero power noise event in the list
|
||||
m_niChanges.erase (++(m_niChanges.begin ()),
|
||||
GetNextPosition (event->GetStartTime ()));
|
||||
}
|
||||
auto first = AddNiChangeEvent (event->GetStartTime (), NiChange (previousPowerStart, event));
|
||||
auto last = AddNiChangeEvent (event->GetEndTime (), NiChange (previousPowerEnd, event));
|
||||
for (auto i = first; i != last; ++i)
|
||||
{
|
||||
i->second.AddPower (event->GetRxPowerW ());
|
||||
WifiSpectrumBand band = it.first;
|
||||
auto ni_it = m_niChangesPerBand.find (band);
|
||||
NS_ASSERT (ni_it != m_niChangesPerBand.end ());
|
||||
double previousPowerStart = 0;
|
||||
double previousPowerEnd = 0;
|
||||
previousPowerStart = GetPreviousPosition (event->GetStartTime (), band)->second.GetPower ();
|
||||
previousPowerEnd = GetPreviousPosition (event->GetEndTime (), band)->second.GetPower ();
|
||||
if (!m_rxing)
|
||||
{
|
||||
m_firstPowerPerBand.find (band)->second = previousPowerStart;
|
||||
// Always leave the first zero power noise event in the list
|
||||
ni_it->second.erase (++(ni_it->second.begin ()), GetNextPosition (event->GetStartTime (), band));
|
||||
}
|
||||
auto first = AddNiChangeEvent (event->GetStartTime (), NiChange (previousPowerStart, event), band);
|
||||
auto last = AddNiChangeEvent (event->GetEndTime (), NiChange (previousPowerEnd, event), band);
|
||||
for (auto i = first; i != last; ++i)
|
||||
{
|
||||
i->second.AddPower (it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << signal << noiseInterference << channelWidth << +nss);
|
||||
//thermal noise at 290K in J/s = W
|
||||
static const double BOLTZMANN = 1.3803e-23;
|
||||
//Nt is the power of thermal noise in W
|
||||
@@ -254,22 +301,30 @@ InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint1
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<Event> event, NiChanges *ni) const
|
||||
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const
|
||||
{
|
||||
double noiseInterferenceW = m_firstPower;
|
||||
auto it = m_niChanges.find (event->GetStartTime ());
|
||||
for (; it != m_niChanges.end () && it->first < Simulator::Now (); ++it)
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
auto firstPower_it = m_firstPowerPerBand.find (band);
|
||||
NS_ASSERT (firstPower_it != m_firstPowerPerBand.end ());
|
||||
double noiseInterferenceW = firstPower_it->second;
|
||||
auto ni_it = m_niChangesPerBand.find (band);
|
||||
NS_ASSERT (ni_it != m_niChangesPerBand.end ());
|
||||
auto it = ni_it->second.find (event->GetStartTime ());
|
||||
for (; it != ni_it->second.end () && it->first < Simulator::Now (); ++it)
|
||||
{
|
||||
noiseInterferenceW = it->second.GetPower () - event->GetRxPowerW ();
|
||||
noiseInterferenceW = it->second.GetPower () - event->GetRxPowerW (band);
|
||||
}
|
||||
it = m_niChanges.find (event->GetStartTime ());
|
||||
for (; it != m_niChanges.end () && it->second.GetEvent () != event; ++it);
|
||||
ni->emplace (event->GetStartTime (), NiChange (0, event));
|
||||
while (++it != m_niChanges.end () && it->second.GetEvent () != event)
|
||||
it = ni_it->second.find (event->GetStartTime ());
|
||||
NS_ASSERT (it != ni_it->second.end ());
|
||||
for (; it != ni_it->second.end () && it->second.GetEvent () != event; ++it);
|
||||
NiChanges ni;
|
||||
ni.emplace (event->GetStartTime (), NiChange (0, event));
|
||||
while (++it != ni_it->second.end () && it->second.GetEvent () != event)
|
||||
{
|
||||
ni->insert (*it);
|
||||
ni.insert (*it);
|
||||
}
|
||||
ni->emplace (event->GetEndTime (), NiChange (0, event));
|
||||
ni.emplace (event->GetEndTime (), NiChange (0, event));
|
||||
nis->insert ({band, ni});
|
||||
NS_ASSERT_MSG (noiseInterferenceW >= 0, "CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
|
||||
return noiseInterferenceW;
|
||||
}
|
||||
@@ -303,30 +358,31 @@ InterferenceHelper::CalculatePayloadChunkSuccessRate (double snir, Time duration
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculatePayloadPer (Ptr<const Event> event, uint16_t staId,
|
||||
NiChanges *ni, std::pair<Time, Time> window) const
|
||||
InterferenceHelper::CalculatePayloadPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band,
|
||||
uint16_t staId, std::pair<Time, Time> window) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << staId << window.first << window.second);
|
||||
NS_LOG_FUNCTION (this << band.first << band.second << staId << window.first << window.second);
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
double psr = 1.0; /* Packet Success Rate */
|
||||
auto j = ni->begin ();
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto j = ni_it.begin ();
|
||||
Time previous = j->first;
|
||||
WifiMode payloadMode = txVector.GetMode (staId);
|
||||
WifiPreamble preamble = txVector.GetPreambleType ();
|
||||
Time phyHeaderStart = j->first + WifiPhy::GetPhyPreambleDuration (txVector); //PPDU start time + preamble
|
||||
Time phyLSigHeaderEnd = phyHeaderStart + WifiPhy::GetPhyHeaderDuration (txVector); //PPDU start time + preamble + L-SIG
|
||||
Time phyTrainingSymbolsStart = phyLSigHeaderEnd + WifiPhy::GetPhyHtSigHeaderDuration (preamble) + WifiPhy::GetPhySigA1Duration (preamble) + WifiPhy::GetPhySigA2Duration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A
|
||||
Time phyHtSigHeaderStart = phyHeaderStart + WifiPhy::GetPhyHeaderDuration (txVector); //PPDU start time + preamble + L-SIG
|
||||
Time phyTrainingSymbolsStart = phyHtSigHeaderStart + WifiPhy::GetPhyHtSigHeaderDuration (preamble) + WifiPhy::GetPhySigA1Duration (preamble) + WifiPhy::GetPhySigA2Duration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A
|
||||
Time phyPayloadStart = phyTrainingSymbolsStart + WifiPhy::GetPhyTrainingSymbolDuration (txVector) + WifiPhy::GetPhySigBDuration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B
|
||||
Time windowStart = phyPayloadStart + window.first;
|
||||
Time windowEnd = phyPayloadStart + window.second;
|
||||
double noiseInterferenceW = m_firstPower;
|
||||
double powerW = event->GetRxPowerW ();
|
||||
while (++j != ni->end ())
|
||||
double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
|
||||
double powerW = event->GetRxPowerW (band);
|
||||
while (++j != ni_it.end ())
|
||||
{
|
||||
Time current = j->first;
|
||||
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
|
||||
NS_ASSERT (current >= previous);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth (), txVector.GetNss (staId));
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, txVector.GetNss (staId));
|
||||
//Case 1: Both previous and current point to the windowed payload
|
||||
if (previous >= windowStart)
|
||||
{
|
||||
@@ -352,12 +408,14 @@ InterferenceHelper::CalculatePayloadPer (Ptr<const Event> event, uint16_t staId,
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChanges *ni) const
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
uint16_t channelWidth = txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth (); //calculate PER on the 20 MHz primary channel for L-SIG
|
||||
double psr = 1.0; /* Packet Success Rate */
|
||||
auto j = ni->begin ();
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto j = ni_it.begin ();
|
||||
Time previous = j->first;
|
||||
WifiPreamble preamble = txVector.GetPreambleType ();
|
||||
WifiMode headerMode = WifiPhy::GetPhyHeaderMode (txVector);
|
||||
@@ -365,14 +423,14 @@ InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChange
|
||||
Time phyLSigHeaderEnd = phyHeaderStart + WifiPhy::GetPhyHeaderDuration (txVector); //PPDU start time + preamble + L-SIG
|
||||
Time phyTrainingSymbolsStart = phyLSigHeaderEnd + WifiPhy::GetPhyHtSigHeaderDuration (preamble) + WifiPhy::GetPhySigA1Duration (preamble) + WifiPhy::GetPhySigA2Duration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A
|
||||
Time phyPayloadStart = phyTrainingSymbolsStart + WifiPhy::GetPhyTrainingSymbolDuration (txVector) + WifiPhy::GetPhySigBDuration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B
|
||||
double noiseInterferenceW = m_firstPower;
|
||||
double powerW = event->GetRxPowerW ();
|
||||
while (++j != ni->end ())
|
||||
double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
|
||||
double powerW = event->GetRxPowerW (band);
|
||||
while (++j != ni_it.end ())
|
||||
{
|
||||
Time current = j->first;
|
||||
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
|
||||
NS_ASSERT (current >= previous);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth (), 1);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
|
||||
//Case 1: previous and current after payload start
|
||||
if (previous >= phyPayloadStart)
|
||||
{
|
||||
@@ -465,12 +523,14 @@ InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChange
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChanges *ni) const
|
||||
InterferenceHelper::CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
const WifiTxVector txVector = event->GetTxVector ();
|
||||
uint16_t channelWidth = txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth (); //calculate PER on the 20 MHz primary channel for PHY headers
|
||||
double psr = 1.0; /* Packet Success Rate */
|
||||
auto j = ni->begin ();
|
||||
auto ni_it = nis->find (band)->second;
|
||||
auto j = ni_it.begin ();
|
||||
Time previous = j->first;
|
||||
WifiPreamble preamble = txVector.GetPreambleType ();
|
||||
WifiMode mcsHeaderMode;
|
||||
@@ -494,14 +554,14 @@ InterferenceHelper::CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChanges *
|
||||
Time phyLSigHeaderEnd = phyHeaderStart + WifiPhy::GetPhyHeaderDuration (txVector); //PPDU start time + preamble + L-SIG
|
||||
Time phyTrainingSymbolsStart = phyLSigHeaderEnd + WifiPhy::GetPhyHtSigHeaderDuration (preamble) + WifiPhy::GetPhySigA1Duration (preamble) + WifiPhy::GetPhySigA2Duration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A
|
||||
Time phyPayloadStart = phyTrainingSymbolsStart + WifiPhy::GetPhyTrainingSymbolDuration (txVector) + WifiPhy::GetPhySigBDuration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B
|
||||
double noiseInterferenceW = m_firstPower;
|
||||
double powerW = event->GetRxPowerW ();
|
||||
while (++j != ni->end ())
|
||||
double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
|
||||
double powerW = event->GetRxPowerW (band);
|
||||
while (++j != ni_it.end ())
|
||||
{
|
||||
Time current = j->first;
|
||||
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
|
||||
NS_ASSERT (current >= previous);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth (), 1);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
|
||||
//Case 1: previous and current after payload start: nothing to do
|
||||
if (previous >= phyPayloadStart)
|
||||
{
|
||||
@@ -731,20 +791,21 @@ InterferenceHelper::CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChanges *
|
||||
}
|
||||
|
||||
struct InterferenceHelper::SnrPer
|
||||
InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t staId,
|
||||
std::pair<Time, Time> relativeMpduStartStop) const
|
||||
InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
|
||||
uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const
|
||||
{
|
||||
NiChanges ni;
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << relativeMpduStartStop.first << relativeMpduStartStop.second);
|
||||
NiChangesPerBand ni;
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (band),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
channelWidth,
|
||||
event->GetTxVector ().GetNss (staId));
|
||||
|
||||
/* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*/
|
||||
double per = CalculatePayloadPer (event, staId, &ni, relativeMpduStartStop);
|
||||
double per = CalculatePayloadPer (event, &ni, band, staId, relativeMpduStartStop);
|
||||
|
||||
struct SnrPer snrPer;
|
||||
snrPer.snr = snr;
|
||||
@@ -753,31 +814,41 @@ InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t staId,
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateSnr (Ptr<Event> event, uint8_t nss) const
|
||||
InterferenceHelper::CalculateSnr (Ptr<Event> event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
|
||||
{
|
||||
NiChanges ni;
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
NiChangesPerBand ni;
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (band),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
channelWidth,
|
||||
nss);
|
||||
return snr;
|
||||
return snr;
|
||||
}
|
||||
|
||||
struct InterferenceHelper::SnrPer
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event) const
|
||||
InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const
|
||||
{
|
||||
NiChanges ni;
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
NiChangesPerBand ni;
|
||||
uint16_t channelWidth;
|
||||
if (event->GetTxVector ().GetChannelWidth () >= 40)
|
||||
{
|
||||
channelWidth = 20; //calculate PER on the 20 MHz primary channel for L-SIG
|
||||
}
|
||||
else
|
||||
{
|
||||
channelWidth = event->GetTxVector ().GetChannelWidth ();
|
||||
}
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (band),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
channelWidth,
|
||||
1);
|
||||
|
||||
/* calculate the SNIR at the start of the PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*/
|
||||
double per = CalculateNonHtPhyHeaderPer (event, &ni);
|
||||
double per = CalculateNonHtPhyHeaderPer (event, &ni, band);
|
||||
|
||||
struct SnrPer snrPer;
|
||||
snrPer.snr = snr;
|
||||
@@ -786,19 +857,29 @@ InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event) const
|
||||
}
|
||||
|
||||
struct InterferenceHelper::SnrPer
|
||||
InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event) const
|
||||
InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const
|
||||
{
|
||||
NiChanges ni;
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
NS_LOG_FUNCTION (this << band.first << band.second);
|
||||
NiChangesPerBand ni;
|
||||
uint16_t channelWidth;
|
||||
if (event->GetTxVector ().GetChannelWidth () >= 40)
|
||||
{
|
||||
channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
|
||||
}
|
||||
else
|
||||
{
|
||||
channelWidth = event->GetTxVector ().GetChannelWidth ();
|
||||
}
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (band),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
channelWidth,
|
||||
1);
|
||||
|
||||
/* calculate the SNIR at the start of the PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*/
|
||||
double per = CalculateHtPhyHeaderPer (event, &ni);
|
||||
double per = CalculateHtPhyHeaderPer (event, &ni, band);
|
||||
|
||||
struct SnrPer snrPer;
|
||||
snrPer.snr = snr;
|
||||
@@ -809,23 +890,28 @@ InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event) const
|
||||
void
|
||||
InterferenceHelper::EraseEvents (void)
|
||||
{
|
||||
m_niChanges.clear ();
|
||||
// Always have a zero power noise event in the list
|
||||
AddNiChangeEvent (Time (0), NiChange (0.0, 0));
|
||||
for (auto it : m_niChangesPerBand)
|
||||
{
|
||||
it.second.clear ();
|
||||
// Always have a zero power noise event in the list
|
||||
AddNiChangeEvent (Time (0), NiChange (0.0, 0), it.first);
|
||||
m_firstPowerPerBand.at (it.first) = 0.0;
|
||||
}
|
||||
m_rxing = false;
|
||||
m_firstPower = 0;
|
||||
}
|
||||
|
||||
InterferenceHelper::NiChanges::const_iterator
|
||||
InterferenceHelper::GetNextPosition (Time moment) const
|
||||
InterferenceHelper::GetNextPosition (Time moment, WifiSpectrumBand band) const
|
||||
{
|
||||
return m_niChanges.upper_bound (moment);
|
||||
auto it = m_niChangesPerBand.find (band);
|
||||
NS_ASSERT (it != m_niChangesPerBand.end ());
|
||||
return it->second.upper_bound (moment);
|
||||
}
|
||||
|
||||
InterferenceHelper::NiChanges::const_iterator
|
||||
InterferenceHelper::GetPreviousPosition (Time moment) const
|
||||
InterferenceHelper::GetPreviousPosition (Time moment, WifiSpectrumBand band) const
|
||||
{
|
||||
auto it = GetNextPosition (moment);
|
||||
auto it = GetNextPosition (moment, band);
|
||||
// This is safe since there is always an NiChange at time 0,
|
||||
// before moment.
|
||||
--it;
|
||||
@@ -833,9 +919,11 @@ InterferenceHelper::GetPreviousPosition (Time moment) const
|
||||
}
|
||||
|
||||
InterferenceHelper::NiChanges::iterator
|
||||
InterferenceHelper::AddNiChangeEvent (Time moment, NiChange change)
|
||||
InterferenceHelper::AddNiChangeEvent (Time moment, NiChange change, WifiSpectrumBand band)
|
||||
{
|
||||
return m_niChanges.insert (GetNextPosition (moment), std::make_pair (moment, change));
|
||||
auto it = m_niChangesPerBand.find (band);
|
||||
NS_ASSERT (it != m_niChangesPerBand.end ());
|
||||
return it->second.insert (GetNextPosition (moment, band), std::make_pair (moment, change));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -851,9 +939,13 @@ InterferenceHelper::NotifyRxEnd ()
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_rxing = false;
|
||||
//Update m_firstPower for frame capture
|
||||
auto it = GetPreviousPosition (Simulator::Now ());
|
||||
it--;
|
||||
m_firstPower = it->second.GetPower ();
|
||||
for (auto ni : m_niChangesPerBand)
|
||||
{
|
||||
NS_ASSERT (ni.second.size () > 1);
|
||||
auto it = GetPreviousPosition (Simulator::Now (), ni.first);
|
||||
it--;
|
||||
m_firstPowerPerBand.find (ni.first)->second = it->second.GetPower ();
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define INTERFERENCE_HELPER_H
|
||||
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/wifi-spectrum-value-helper.h"
|
||||
#include "wifi-tx-vector.h"
|
||||
#include <map>
|
||||
|
||||
@@ -31,6 +32,11 @@ class WifiPpdu;
|
||||
class WifiPsdu;
|
||||
class ErrorRateModel;
|
||||
|
||||
/**
|
||||
* A map of the received power (Watts) for each band
|
||||
*/
|
||||
typedef std::map <WifiSpectrumBand, double> RxPowerWattPerChannelBand;
|
||||
|
||||
/**
|
||||
* \ingroup wifi
|
||||
* \brief handles interference calculations
|
||||
@@ -45,9 +51,9 @@ public:
|
||||
* \param ppdu the PPDU
|
||||
* \param txVector the TXVECTOR
|
||||
* \param duration duration of the PPDU
|
||||
* \param rxPower the received power (w)
|
||||
* \param rxPower the received power per band (W)
|
||||
*/
|
||||
Event (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, double rxPower);
|
||||
Event (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, RxPowerWattPerChannelBand rxPower);
|
||||
~Event ();
|
||||
|
||||
/**
|
||||
@@ -75,11 +81,24 @@ public:
|
||||
*/
|
||||
Time GetDuration (void) const;
|
||||
/**
|
||||
* Return the received power (w).
|
||||
* Return the total received power (W).
|
||||
*
|
||||
* \return the received power (w)
|
||||
* \return the total received power (W)
|
||||
*/
|
||||
double GetRxPowerW (void) const;
|
||||
/**
|
||||
* Return the received power (W) for a given band.
|
||||
*
|
||||
* \param band the band for which the power should be returned
|
||||
* \return the received power (W) for a given band
|
||||
*/
|
||||
double GetRxPowerW (WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Return the received power (W) for all bands.
|
||||
*
|
||||
* \return the received power (W) for all bands.
|
||||
*/
|
||||
RxPowerWattPerChannelBand GetRxPowerWPerBand (void) const;
|
||||
/**
|
||||
* Return the TXVECTOR of the PPDU.
|
||||
*
|
||||
@@ -89,11 +108,11 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
Ptr<const WifiPpdu> m_ppdu; ///< PPDU
|
||||
WifiTxVector m_txVector; ///< TXVECTOR
|
||||
Time m_startTime; ///< start time
|
||||
Time m_endTime; ///< end time
|
||||
double m_rxPowerW; ///< received power in watts
|
||||
Ptr<const WifiPpdu> m_ppdu; //!< PPDU
|
||||
WifiTxVector m_txVector; //!< TXVECTOR
|
||||
Time m_startTime; //!< start time
|
||||
Time m_endTime; //!< end time
|
||||
RxPowerWattPerChannelBand m_rxPowerW; //!< received power in watts per band
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -129,6 +148,18 @@ public:
|
||||
InterferenceHelper ();
|
||||
~InterferenceHelper ();
|
||||
|
||||
/**
|
||||
* Add a frequency band.
|
||||
*
|
||||
* \param band the band to be created
|
||||
*/
|
||||
void AddBand (WifiSpectrumBand band);
|
||||
|
||||
/**
|
||||
* Remove the frequency bands.
|
||||
*/
|
||||
void RemoveBands (void);
|
||||
|
||||
/**
|
||||
* Set the noise figure.
|
||||
*
|
||||
@@ -158,30 +189,32 @@ public:
|
||||
|
||||
/**
|
||||
* \param energyW the minimum energy (W) requested
|
||||
* \param band identify the requested band
|
||||
*
|
||||
* \returns the expected amount of time the observed
|
||||
* energy on the medium will be higher than
|
||||
* the requested threshold.
|
||||
* energy on the medium for a given band will
|
||||
* be higher than the requested threshold.
|
||||
*/
|
||||
Time GetEnergyDuration (double energyW) const;
|
||||
Time GetEnergyDuration (double energyW, WifiSpectrumBand band) const;
|
||||
|
||||
/**
|
||||
* Add the PPDU-related signal to interference helper.
|
||||
*
|
||||
* \param ppdu the PPDU
|
||||
* \param txVector the TXVECTOR
|
||||
* \param rxPower received power (W)
|
||||
* \param duration the PPDU duration
|
||||
* \param rxPower received power per band (W)
|
||||
*
|
||||
* \return Event
|
||||
*/
|
||||
Ptr<Event> Add (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, double rxPower);
|
||||
Ptr<Event> Add (Ptr<const WifiPpdu> ppdu, WifiTxVector txVector, Time duration, RxPowerWattPerChannelBand rxPower);
|
||||
|
||||
/**
|
||||
* Add a non-Wifi signal to interference helper.
|
||||
* \param duration the duration of the signal
|
||||
* \param rxPower received power (W)
|
||||
* \param rxPower received power per band (W)
|
||||
*/
|
||||
void AddForeignSignal (Time duration, double rxPower);
|
||||
void AddForeignSignal (Time duration, RxPowerWattPerChannelBand rxPower);
|
||||
/**
|
||||
* Calculate the SNIR at the start of the payload and accumulate
|
||||
* all SNIR changes in the SNIR vector for each MPDU of an A-MPDU.
|
||||
@@ -190,40 +223,46 @@ public:
|
||||
* this class.
|
||||
*
|
||||
* \param event the event corresponding to the first time the corresponding PPDU arrives
|
||||
* \param channelWidth the channel width used to transmit the PSDU (in MHz)
|
||||
* \param band identify the band used by the PSDU
|
||||
* \param staId the station ID of the PSDU (only used for MU)
|
||||
* \param relativeMpduStartStop the time window (pair of start and end times) of PHY payload to focus on
|
||||
*
|
||||
* \return struct of SNR and PER (with PER being evaluated over the provided time window)
|
||||
*/
|
||||
struct InterferenceHelper::SnrPer CalculatePayloadSnrPer (Ptr<Event> event, uint16_t staId,
|
||||
std::pair<Time, Time> relativeMpduStartStop) const;
|
||||
struct InterferenceHelper::SnrPer CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
|
||||
uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const;
|
||||
/**
|
||||
* Calculate the SNIR for the event (starting from now until the event end).
|
||||
*
|
||||
* \param event the event corresponding to the first time the corresponding PPDU arrives
|
||||
* \param channelWidth the channel width (in MHz)
|
||||
* \param nss the number of spatial streams
|
||||
* \param band identify the band used by the PSDU
|
||||
*
|
||||
* \return the SNR for the PPDU in linear scale
|
||||
*/
|
||||
double CalculateSnr (Ptr<Event> event, uint8_t nss) const;
|
||||
double CalculateSnr (Ptr<Event> event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Calculate the SNIR at the start of the non-HT PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*
|
||||
* \param event the event corresponding to the first time the corresponding PPDU arrives
|
||||
* \param band identify the band used by the PSDU
|
||||
*
|
||||
* \return struct of SNR and PER
|
||||
*/
|
||||
struct InterferenceHelper::SnrPer CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event) const;
|
||||
struct InterferenceHelper::SnrPer CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Calculate the SNIR at the start of the HT PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
*
|
||||
* \param event the event corresponding to the first time the corresponding PPDU arrives
|
||||
* \param band identify the band used by the PSDU
|
||||
*
|
||||
* \return struct of SNR and PER
|
||||
*/
|
||||
struct InterferenceHelper::SnrPer CalculateHtPhyHeaderSnrPer (Ptr<Event> event) const;
|
||||
struct InterferenceHelper::SnrPer CalculateHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const;
|
||||
|
||||
/**
|
||||
* Notify that RX has started.
|
||||
@@ -305,10 +344,15 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* typedef for a multimap of NiChanges
|
||||
* typedef for a multimap of NiChange
|
||||
*/
|
||||
typedef std::multimap<Time, NiChange> NiChanges;
|
||||
|
||||
/**
|
||||
* Map of NiChanges per band
|
||||
*/
|
||||
typedef std::map <WifiSpectrumBand, NiChanges> NiChangesPerBand;
|
||||
|
||||
/**
|
||||
* Append the given Event.
|
||||
*
|
||||
@@ -319,11 +363,12 @@ private:
|
||||
* Calculate noise and interference power in W.
|
||||
*
|
||||
* \param event the event
|
||||
* \param ni the NiChanges
|
||||
* \param nis the NiChanges
|
||||
* \param band the band
|
||||
*
|
||||
* \return noise and interference power
|
||||
*/
|
||||
double CalculateNoiseInterferenceW (Ptr<Event> event, NiChanges *ni) const;
|
||||
double CalculateNoiseInterferenceW (Ptr<Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Calculate the success rate of the payload chunk given the SINR, duration, and Wi-Fi mode.
|
||||
* The duration and mode are used to calculate how many bits are present in the chunk.
|
||||
@@ -342,64 +387,61 @@ private:
|
||||
* multiple chunks (e.g. due to interference from other transmissions).
|
||||
*
|
||||
* \param event the event
|
||||
* \param nis the NiChanges
|
||||
* \param band identify the band used by the PSDU
|
||||
* \param staId the station ID of the PSDU (only used for MU)
|
||||
* \param ni the NiChanges
|
||||
* \param window time window (pair of start and end times) of PHY payload to focus on
|
||||
*
|
||||
* \return the error rate of the payload
|
||||
*/
|
||||
double CalculatePayloadPer (Ptr<const Event> event, uint16_t staId,
|
||||
NiChanges *ni, std::pair<Time, Time> window) const;
|
||||
double CalculatePayloadPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band,
|
||||
uint16_t staId, std::pair<Time, Time> window) const;
|
||||
/**
|
||||
* Calculate the error rate of the non-HT PHY header. The non-HT PHY header
|
||||
* can be divided into multiple chunks (e.g. due to interference from other transmissions).
|
||||
*
|
||||
* \param event the event
|
||||
* \param ni the NiChanges
|
||||
* \param nis the NiChanges
|
||||
* \param band the band
|
||||
*
|
||||
* \return the error rate of the non-HT PHY header
|
||||
*/
|
||||
double CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChanges *ni) const;
|
||||
double CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Calculate the error rate of the HT PHY header. TheHT PHY header
|
||||
* can be divided into multiple chunks (e.g. due to interference from other transmissions).
|
||||
*
|
||||
* \param event the event
|
||||
* \param ni the NiChanges
|
||||
* \param nis the NiChanges
|
||||
* \param band the band
|
||||
*
|
||||
* \return the error rate of the HT PHY header
|
||||
*/
|
||||
double CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChanges *ni) const;
|
||||
double CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChangesPerBand *nis, WifiSpectrumBand band) const;
|
||||
|
||||
double m_noiseFigure; /**< noise figure (linear) */
|
||||
Ptr<ErrorRateModel> m_errorRateModel; ///< error rate model
|
||||
uint8_t m_numRxAntennas; /**< the number of RX antennas in the corresponding receiver */
|
||||
/// Experimental: needed for energy duration calculation
|
||||
NiChanges m_niChanges;
|
||||
double m_firstPower; ///< first power in watts
|
||||
bool m_rxing; ///< flag whether it is in receiving state
|
||||
double m_noiseFigure; //!< noise figure (linear)
|
||||
Ptr<ErrorRateModel> m_errorRateModel; //!< error rate model
|
||||
uint8_t m_numRxAntennas; //!< the number of RX antennas in the corresponding receiver
|
||||
NiChangesPerBand m_niChangesPerBand; //!< NI Changes for each band
|
||||
std::map <WifiSpectrumBand, double> m_firstPowerPerBand; //!< first power of each band in watts
|
||||
bool m_rxing; //!< flag whether it is in receiving state
|
||||
|
||||
/**
|
||||
* Returns an iterator to the first NiChange that is later than moment
|
||||
*
|
||||
* \param moment time to check from
|
||||
* \param band identify the band to check
|
||||
* \returns an iterator to the list of NiChanges
|
||||
*/
|
||||
NiChanges::const_iterator GetNextPosition (Time moment) const;
|
||||
/**
|
||||
* Returns an iterator to the first NiChange that is later than moment
|
||||
*
|
||||
* \param moment time to check from
|
||||
* \returns an iterator to the list of NiChanges
|
||||
*/
|
||||
//NiChanges::iterator GetNextPosition (Time moment);
|
||||
NiChanges::const_iterator GetNextPosition (Time moment, WifiSpectrumBand band) const;
|
||||
/**
|
||||
* Returns an iterator to the last NiChange that is before than moment
|
||||
*
|
||||
* \param moment time to check from
|
||||
* \param band identify the band to check
|
||||
* \returns an iterator to the list of NiChanges
|
||||
*/
|
||||
NiChanges::const_iterator GetPreviousPosition (Time moment) const;
|
||||
NiChanges::const_iterator GetPreviousPosition (Time moment, WifiSpectrumBand band) const;
|
||||
|
||||
/**
|
||||
* Add NiChange to the list at the appropriate position and
|
||||
@@ -407,9 +449,10 @@ private:
|
||||
*
|
||||
* \param moment time to check from
|
||||
* \param change the NiChange to add
|
||||
* \param band identify the band to check
|
||||
* \returns the iterator of the new event
|
||||
*/
|
||||
NiChanges::iterator AddNiChangeEvent (Time moment, NiChange change);
|
||||
NiChanges::iterator AddNiChangeEvent (Time moment, NiChange change, WifiSpectrumBand band);
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* with Nicola Baldo and Dean Armstrong
|
||||
*/
|
||||
|
||||
#include "ns3/wifi-spectrum-value-helper.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/net-device.h"
|
||||
@@ -96,7 +95,7 @@ SpectrumWifiPhy::DoInitialize (void)
|
||||
}
|
||||
|
||||
Ptr<const SpectrumModel>
|
||||
SpectrumWifiPhy::GetRxSpectrumModel () const
|
||||
SpectrumWifiPhy::GetRxSpectrumModel ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_rxSpectrumModel)
|
||||
@@ -115,11 +114,35 @@ SpectrumWifiPhy::GetRxSpectrumModel () const
|
||||
uint16_t channelWidth = GetChannelWidth ();
|
||||
NS_LOG_DEBUG ("Creating spectrum model from frequency/width pair of (" << GetFrequency () << ", " << channelWidth << ")");
|
||||
m_rxSpectrumModel = WifiSpectrumValueHelper::GetSpectrumModel (GetFrequency (), channelWidth, GetBandBandwidth (), GetGuardBandwidth (channelWidth));
|
||||
UpdateInterferenceHelperBands ();
|
||||
}
|
||||
}
|
||||
return m_rxSpectrumModel;
|
||||
}
|
||||
|
||||
void
|
||||
SpectrumWifiPhy::UpdateInterferenceHelperBands (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
uint16_t channelWidth = GetChannelWidth ();
|
||||
m_interference.RemoveBands ();
|
||||
if (channelWidth < 20)
|
||||
{
|
||||
WifiSpectrumBand band = GetBand (channelWidth);
|
||||
m_interference.AddBand (band);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
|
||||
{
|
||||
for (uint8_t i = 0; i < (channelWidth / bw); ++i)
|
||||
{
|
||||
m_interference.AddBand (GetBand (bw, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Channel>
|
||||
SpectrumWifiPhy::GetChannel (void) const
|
||||
{
|
||||
@@ -143,6 +166,7 @@ SpectrumWifiPhy::ResetSpectrumModel (void)
|
||||
// on the SpectrumChannel to provide this new spectrum model to it
|
||||
m_rxSpectrumModel = WifiSpectrumValueHelper::GetSpectrumModel (GetFrequency (), channelWidth, GetBandBandwidth (), GetGuardBandwidth (channelWidth));
|
||||
m_channel->AddRx (m_wifiSpectrumPhyInterface);
|
||||
UpdateInterferenceHelperBands ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -202,27 +226,67 @@ SpectrumWifiPhy::StartRx (Ptr<SpectrumSignalParameters> rxParams)
|
||||
senderNodeId = rxParams->txPhy->GetDevice ()->GetNode ()->GetId ();
|
||||
}
|
||||
NS_LOG_DEBUG ("Received signal from " << senderNodeId << " with unfiltered power " << WToDbm (Integral (*receivedSignalPsd)) << " dBm");
|
||||
|
||||
// Integrate over our receive bandwidth (i.e., all that the receive
|
||||
// spectral mask representing our filtering allows) to find the
|
||||
// total energy apparent to the "demodulator".
|
||||
// This is done per 20 MHz channel band.
|
||||
uint16_t channelWidth = GetChannelWidth ();
|
||||
Ptr<SpectrumValue> filter = WifiSpectrumValueHelper::CreateRfFilter (GetFrequency (), channelWidth, GetBandBandwidth (), GetGuardBandwidth (channelWidth));
|
||||
SpectrumValue filteredSignal = (*filter) * (*receivedSignalPsd);
|
||||
// Add receiver antenna gain
|
||||
NS_LOG_DEBUG ("Signal power received (watts) before antenna gain: " << Integral (filteredSignal));
|
||||
double rxPowerW = Integral (filteredSignal) * DbToRatio (GetRxGain ());
|
||||
NS_LOG_DEBUG ("Signal power received after antenna gain: " << rxPowerW << " W (" << WToDbm (rxPowerW) << " dBm)");
|
||||
double totalRxPowerW = 0;
|
||||
RxPowerWattPerChannelBand rxPowerW;
|
||||
|
||||
if ((channelWidth == 5) || (channelWidth == 10))
|
||||
{
|
||||
WifiSpectrumBand filteredBand = GetBand (channelWidth);
|
||||
Ptr<SpectrumValue> filter = WifiSpectrumValueHelper::CreateRfFilter (GetFrequency (), channelWidth, GetBandBandwidth (), GetGuardBandwidth (channelWidth), filteredBand);
|
||||
SpectrumValue filteredSignal = (*filter) * (*receivedSignalPsd);
|
||||
NS_LOG_DEBUG ("Signal power received (watts) before antenna gain: " << Integral (filteredSignal));
|
||||
double rxPowerPerBandW = Integral (filteredSignal) * DbToRatio (GetRxGain ());
|
||||
totalRxPowerW += rxPowerPerBandW;
|
||||
rxPowerW.insert ({filteredBand, rxPowerPerBandW});
|
||||
NS_LOG_DEBUG ("Signal power received after antenna gain for " << channelWidth << " MHz channel: " << rxPowerPerBandW << " W (" << WToDbm (rxPowerPerBandW) << " dBm)");
|
||||
}
|
||||
|
||||
for (uint16_t bw = 160; bw > 20; bw = bw / 2) //20 MHz is handled apart since the totalRxPowerW is computed through it
|
||||
{
|
||||
for (uint8_t i = 0; i < (channelWidth / bw); i++)
|
||||
{
|
||||
NS_ASSERT (channelWidth >= bw);
|
||||
WifiSpectrumBand filteredBand = GetBand (bw, i);
|
||||
Ptr<SpectrumValue> filter = WifiSpectrumValueHelper::CreateRfFilter (GetFrequency (), channelWidth, GetBandBandwidth (), GetGuardBandwidth (channelWidth), filteredBand);
|
||||
SpectrumValue filteredSignal = (*filter) * (*receivedSignalPsd);
|
||||
NS_LOG_DEBUG ("Signal power received (watts) before antenna gain for" << bw << " MHz channel band " << +i << ": " << Integral (filteredSignal));
|
||||
double rxPowerPerBandW = Integral (filteredSignal) * DbToRatio (GetRxGain ());
|
||||
rxPowerW.insert ({filteredBand, rxPowerPerBandW});
|
||||
NS_LOG_DEBUG ("Signal power received after antenna gain for" << bw << " MHz channel band " << +i << ": " << rxPowerPerBandW << " W (" << WToDbm (rxPowerPerBandW) << " dBm)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (uint8_t i = 0; i < (channelWidth / 20); i++)
|
||||
{
|
||||
WifiSpectrumBand filteredBand = GetBand (20, i);
|
||||
Ptr<SpectrumValue> filter = WifiSpectrumValueHelper::CreateRfFilter (GetFrequency (), channelWidth, GetBandBandwidth (), GetGuardBandwidth (channelWidth), filteredBand);
|
||||
SpectrumValue filteredSignal = (*filter) * (*receivedSignalPsd);
|
||||
NS_LOG_DEBUG ("Signal power received (watts) before antenna gain for 20 MHz channel band " << +i << ": " << Integral (filteredSignal));
|
||||
double rxPowerPerBandW = Integral (filteredSignal) * DbToRatio (GetRxGain ());
|
||||
totalRxPowerW += rxPowerPerBandW;
|
||||
rxPowerW.insert ({filteredBand, rxPowerPerBandW});
|
||||
NS_LOG_DEBUG ("Signal power received after antenna gain for 20 MHz channel band " << +i << ": " << rxPowerPerBandW << " W (" << WToDbm (rxPowerPerBandW) << " dBm)");
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("Total signal power received after antenna gain: " << totalRxPowerW << " W (" << WToDbm (totalRxPowerW) << " dBm)");
|
||||
|
||||
Ptr<WifiSpectrumSignalParameters> wifiRxParams = DynamicCast<WifiSpectrumSignalParameters> (rxParams);
|
||||
|
||||
// Log the signal arrival to the trace source
|
||||
m_signalCb (wifiRxParams ? true : false, senderNodeId, WToDbm (rxPowerW), rxDuration);
|
||||
m_signalCb (wifiRxParams ? true : false, senderNodeId, WToDbm (totalRxPowerW), rxDuration);
|
||||
|
||||
// Do no further processing if signal is too weak
|
||||
// Current implementation assumes constant RX power over the PPDU duration
|
||||
if (WToDbm (rxPowerW) < GetRxSensitivity ())
|
||||
if (WToDbm (totalRxPowerW) < GetRxSensitivity ())
|
||||
{
|
||||
NS_LOG_INFO ("Received signal too weak to process: " << WToDbm (rxPowerW) << " dBm");
|
||||
NS_LOG_INFO ("Received signal too weak to process: " << WToDbm (totalRxPowerW) << " dBm");
|
||||
return;
|
||||
}
|
||||
if (wifiRxParams == 0)
|
||||
@@ -393,4 +457,29 @@ SpectrumWifiPhy::GetGuardBandwidth (uint16_t currentChannelWidth) const
|
||||
return guardBandwidth;
|
||||
}
|
||||
|
||||
WifiSpectrumBand
|
||||
SpectrumWifiPhy::GetBand (uint16_t bandWidth, uint8_t bandIndex)
|
||||
{
|
||||
uint16_t channelWidth = GetChannelWidth ();
|
||||
uint32_t bandBandwidth = GetBandBandwidth ();
|
||||
size_t numBandsInChannel = static_cast<size_t> (channelWidth * 1e6 / bandBandwidth);
|
||||
size_t numBandsInBand = static_cast<size_t> (bandWidth * 1e6 / bandBandwidth);
|
||||
if (numBandsInBand % 2 == 0)
|
||||
{
|
||||
numBandsInChannel += 1; // symmetry around center frequency
|
||||
}
|
||||
size_t totalNumBands = GetRxSpectrumModel ()->GetNumBands ();
|
||||
NS_ASSERT_MSG ((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1), "Should have odd number of bands");
|
||||
NS_ASSERT_MSG ((bandIndex * bandWidth) < channelWidth, "Band index is out of bound");
|
||||
WifiSpectrumBand band;
|
||||
band.first = ((totalNumBands - numBandsInChannel) / 2) + (bandIndex * numBandsInBand);
|
||||
if (band.first >= totalNumBands / 2)
|
||||
{
|
||||
//step past DC
|
||||
band.first += 1;
|
||||
}
|
||||
band.second = band.first + numBandsInBand - 1;
|
||||
return band;
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
* for all SpectrumValues that are passed to StartRx. If 0 is
|
||||
* returned, it means that any model will be accepted.
|
||||
*/
|
||||
Ptr<const SpectrumModel> GetRxSpectrumModel () const;
|
||||
Ptr<const SpectrumModel> GetRxSpectrumModel ();
|
||||
|
||||
/**
|
||||
* \return the width of each band (Hz)
|
||||
@@ -158,11 +158,22 @@ public:
|
||||
virtual void ConfigureStandardAndBand (WifiPhyStandard standard, WifiPhyBand band);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
// Inherited
|
||||
void DoDispose (void);
|
||||
void DoInitialize (void);
|
||||
|
||||
/**
|
||||
* Get the start band index and the stop band index for a given band
|
||||
*
|
||||
* \param bandWidth the width of the band to be returned (MHz)
|
||||
* \param bandIndex the index of the band to be returned
|
||||
*
|
||||
* \return a pair of start and stop indexes that defines the band
|
||||
*/
|
||||
WifiSpectrumBand GetBand (uint16_t bandWidth, uint8_t bandIndex = 0);
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -181,6 +192,10 @@ private:
|
||||
* Perform run-time spectrum model change
|
||||
*/
|
||||
void ResetSpectrumModel (void);
|
||||
/**
|
||||
* This function is called to update the bands handled by the InterferenceHelper.
|
||||
*/
|
||||
void UpdateInterferenceHelperBands (void);
|
||||
|
||||
Ptr<SpectrumChannel> m_channel; //!< SpectrumChannel that this SpectrumWifiPhy is connected to
|
||||
|
||||
|
||||
@@ -195,13 +195,10 @@ LSigHeader::GetSerializedSize (void) const
|
||||
void
|
||||
LSigHeader::SetRate (uint64_t rate, uint16_t channelWidth)
|
||||
{
|
||||
if (channelWidth == 5)
|
||||
if (channelWidth < 20)
|
||||
{
|
||||
rate *= 4; //corresponding 20 MHz rate if 5 MHz is used
|
||||
}
|
||||
else if (channelWidth == 10)
|
||||
{
|
||||
rate *= 2; //corresponding 20 MHz rate if 10 MHz is used
|
||||
//conversion for 5 MHz and 10 MHz
|
||||
rate *= (20 / channelWidth);
|
||||
}
|
||||
/* Here is the binary representation for a given rate:
|
||||
* 6 Mbit/s: 1101
|
||||
|
||||
@@ -1854,7 +1854,8 @@ WifiPhy::ResumeFromSleep (void)
|
||||
case WifiPhyState::SLEEP:
|
||||
{
|
||||
NS_LOG_DEBUG ("resuming from sleep mode");
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW);
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
m_state->SwitchFromSleep (delayUntilCcaEnd);
|
||||
break;
|
||||
}
|
||||
@@ -1885,7 +1886,8 @@ WifiPhy::ResumeFromOff (void)
|
||||
case WifiPhyState::OFF:
|
||||
{
|
||||
NS_LOG_DEBUG ("resuming from off mode");
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW);
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
m_state->SwitchFromOff (delayUntilCcaEnd);
|
||||
break;
|
||||
}
|
||||
@@ -2797,11 +2799,21 @@ WifiPhy::StartReceiveHeader (Ptr<Event> event)
|
||||
NS_ASSERT (event->GetStartTime () == m_currentEvent->GetStartTime ());
|
||||
NS_ASSERT (event->GetEndTime () == m_currentEvent->GetEndTime ());
|
||||
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateNonHtPhyHeaderSnrPer (event);
|
||||
uint16_t channelWidth;
|
||||
if (event->GetTxVector ().GetChannelWidth () >= 40)
|
||||
{
|
||||
channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
|
||||
}
|
||||
else
|
||||
{
|
||||
channelWidth = event->GetTxVector ().GetChannelWidth ();
|
||||
}
|
||||
auto band = GetBand (channelWidth);
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateNonHtPhyHeaderSnrPer (event, band);
|
||||
double snr = snrPer.snr;
|
||||
NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
|
||||
|
||||
if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (event->GetRxPowerW (), snr, m_channelWidth)))
|
||||
if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (event->GetRxPowerW (band), snr, m_channelWidth)))
|
||||
{
|
||||
NotifyRxBegin (GetAddressedPsduInPpdu (event->GetPpdu ()));
|
||||
|
||||
@@ -2845,10 +2857,19 @@ WifiPhy::ContinueReceiveHeader (Ptr<Event> event)
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
NS_ASSERT (m_endPhyRxEvent.IsExpired ());
|
||||
|
||||
InterferenceHelper::SnrPer snrPer;
|
||||
snrPer = m_interference.CalculateNonHtPhyHeaderSnrPer (event);
|
||||
uint16_t channelWidth;
|
||||
if (event->GetTxVector ().GetChannelWidth () >= 40)
|
||||
{
|
||||
channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
|
||||
}
|
||||
else
|
||||
{
|
||||
channelWidth = event->GetTxVector ().GetChannelWidth ();
|
||||
}
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateNonHtPhyHeaderSnrPer (event, GetBand (channelWidth));
|
||||
|
||||
if (m_random->GetValue () > snrPer.per) //non-HT PHY header reception succeeded
|
||||
NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
|
||||
if (m_random->GetValue () > snrPer.per) //legacy PHY header reception succeeded
|
||||
{
|
||||
NS_LOG_DEBUG ("Received non-HT PHY header");
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
@@ -2869,12 +2890,17 @@ WifiPhy::ContinueReceiveHeader (Ptr<Event> event)
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, double rxPowerW)
|
||||
WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *ppdu << rxPowerW);
|
||||
//The total RX power corresponds to the maximum over all the bands
|
||||
auto it = std::max_element (rxPowersW.begin (), rxPowersW.end (),
|
||||
[] (const std::pair<WifiSpectrumBand, double>& p1, const std::pair<WifiSpectrumBand, double>& p2) {
|
||||
return p1.second < p2.second;
|
||||
});
|
||||
NS_LOG_FUNCTION (this << *ppdu << it->second);
|
||||
WifiTxVector txVector = ppdu->GetTxVector ();
|
||||
Time rxDuration = ppdu->GetTxDuration ();
|
||||
Ptr<Event> event = m_interference.Add (ppdu, txVector, rxDuration, rxPowerW);
|
||||
Ptr<Event> event = m_interference.Add (ppdu, txVector, rxDuration, rxPowersW);
|
||||
Time endRx = Simulator::Now () + rxDuration;
|
||||
|
||||
if (m_state->GetState () == WifiPhyState::OFF)
|
||||
@@ -2936,12 +2962,11 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, double rxPowerW)
|
||||
{
|
||||
AbortCurrentReception (FRAME_CAPTURE_PACKET_SWITCH);
|
||||
NS_LOG_DEBUG ("Switch to new packet");
|
||||
StartRx (event, rxPowerW);
|
||||
StartRx (event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because already in Rx (power=" <<
|
||||
rxPowerW << "W)");
|
||||
NS_LOG_DEBUG ("Drop packet because already in Rx");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), RXING);
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
@@ -2951,8 +2976,7 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, double rxPowerW)
|
||||
}
|
||||
break;
|
||||
case WifiPhyState::TX:
|
||||
NS_LOG_DEBUG ("Drop packet because already in Tx (power=" <<
|
||||
rxPowerW << "W)");
|
||||
NS_LOG_DEBUG ("Drop packet because already in Tx");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (ppdu), TXING);
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
@@ -2969,12 +2993,11 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, double rxPowerW)
|
||||
{
|
||||
AbortCurrentReception (FRAME_CAPTURE_PACKET_SWITCH);
|
||||
NS_LOG_DEBUG ("Switch to new packet");
|
||||
StartRx (event, rxPowerW);
|
||||
StartRx (event);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because already in Rx (power=" <<
|
||||
rxPowerW << "W)");
|
||||
NS_LOG_DEBUG ("Drop packet because already in Rx");
|
||||
NotifyRxDrop (ppdu->GetPsdu (), RXING);
|
||||
if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
|
||||
{
|
||||
@@ -2985,11 +3008,11 @@ WifiPhy::StartReceivePreamble (Ptr<WifiPpdu> ppdu, double rxPowerW)
|
||||
}
|
||||
else
|
||||
{
|
||||
StartRx (event, rxPowerW);
|
||||
StartRx (event);
|
||||
}
|
||||
break;
|
||||
case WifiPhyState::IDLE:
|
||||
StartRx (event, rxPowerW);
|
||||
StartRx (event);
|
||||
break;
|
||||
case WifiPhyState::SLEEP:
|
||||
NS_LOG_DEBUG ("Drop packet because in sleep mode");
|
||||
@@ -3013,8 +3036,8 @@ WifiPhy::MaybeCcaBusyDuration ()
|
||||
//not going to be able to synchronize on it
|
||||
//In this model, CCA becomes busy when the aggregation of all signals as
|
||||
//tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
|
||||
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW);
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
if (!delayUntilCcaEnd.IsZero ())
|
||||
{
|
||||
m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
|
||||
@@ -3030,10 +3053,12 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
bool canReceivePayload = false;
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
WifiModulationClass modulation = ppdu->GetModulation ();
|
||||
//calculate PER on the primary 20 MHz channel for PHY headers
|
||||
uint16_t primaryChannelWidth = std::min (event->GetTxVector ().GetChannelWidth (), static_cast<uint16_t> (20));
|
||||
auto primaryBand = GetBand (primaryChannelWidth);
|
||||
if (modulation >= WIFI_MOD_CLASS_HT)
|
||||
{
|
||||
InterferenceHelper::SnrPer snrPer;
|
||||
snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event);
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event, primaryBand);
|
||||
NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
|
||||
canReceivePayload = (m_random->GetValue () > snrPer.per);
|
||||
}
|
||||
@@ -3103,7 +3128,7 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
if (modulation == WIFI_MOD_CLASS_HE)
|
||||
{
|
||||
HePreambleParameters params;
|
||||
params.rssiW = event->GetRxPowerW ();
|
||||
params.rssiW = event->GetRxPowerW (primaryBand);
|
||||
params.bssColor = event->GetTxVector ().GetBssColor ();
|
||||
NotifyEndOfHePreamble (params);
|
||||
}
|
||||
@@ -3177,7 +3202,8 @@ WifiPhy::EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
uint16_t staId = GetStaId ();
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
double snr = m_interference.CalculateSnr (event, txVector.GetNss (staId));
|
||||
uint16_t channelWidth = std::min (GetChannelWidth (), txVector.GetChannelWidth ());
|
||||
double snr = m_interference.CalculateSnr (event, channelWidth, txVector.GetNss (staId), GetBand (channelWidth));
|
||||
|
||||
std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, staId, relativeStart, mpduDuration);
|
||||
NS_LOG_DEBUG ("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.GetNanoSeconds () << "ns" <<
|
||||
@@ -3212,7 +3238,8 @@ WifiPhy::EndReceive (Ptr<Event> event)
|
||||
|
||||
NotifyRxEnd (psdu);
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
double snr = m_interference.CalculateSnr (event, txVector.GetNss (staId));
|
||||
uint16_t channelWidth = std::min (GetChannelWidth (), txVector.GetChannelWidth ());
|
||||
double snr = m_interference.CalculateSnr (event, channelWidth, txVector.GetNss (staId), GetBand (channelWidth));
|
||||
if (std::count (m_statusPerMpdu.begin (), m_statusPerMpdu.end (), true))
|
||||
{
|
||||
//At least one MPDU has been successfully received
|
||||
@@ -3235,8 +3262,8 @@ WifiPhy::GetReceptionStatus (Ptr<const WifiPsdu> psdu, Ptr<Event> event, uint16_
|
||||
Time relativeMpduStart, Time mpduDuration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *psdu << *event << staId << relativeMpduStart << mpduDuration);
|
||||
InterferenceHelper::SnrPer snrPer;
|
||||
snrPer = m_interference.CalculatePayloadSnrPer (event, staId, std::make_pair (relativeMpduStart, relativeMpduStart + mpduDuration));
|
||||
uint16_t channelWidth = std::min (GetChannelWidth (), event->GetTxVector ().GetChannelWidth ());
|
||||
InterferenceHelper::SnrPer snrPer = m_interference.CalculatePayloadSnrPer (event, channelWidth, GetBand (channelWidth), staId, std::make_pair (relativeMpduStart, relativeMpduStart + mpduDuration));
|
||||
|
||||
WifiMode mode = event->GetTxVector ().GetMode (staId);
|
||||
NS_LOG_DEBUG ("mode=" << (mode.GetDataRate (event->GetTxVector (), staId)) <<
|
||||
@@ -3248,8 +3275,8 @@ WifiPhy::GetReceptionStatus (Ptr<const WifiPsdu> psdu, Ptr<Event> event, uint16_
|
||||
// Receive error model is optional, if we have an error model and
|
||||
// it indicates that the packet is corrupt, drop the packet.
|
||||
SignalNoiseDbm signalNoise;
|
||||
signalNoise.signal = WToDbm (event->GetRxPowerW ());
|
||||
signalNoise.noise = WToDbm (event->GetRxPowerW () / snrPer.snr);
|
||||
signalNoise.signal = WToDbm (event->GetRxPowerW (GetBand (channelWidth)));
|
||||
signalNoise.noise = WToDbm (event->GetRxPowerW (GetBand (channelWidth)) / snrPer.snr);
|
||||
if (m_random->GetValue () > snrPer.per &&
|
||||
!(m_postReceptionErrorModel && m_postReceptionErrorModel->IsCorrupt (psdu->GetPacket ()->Copy ())))
|
||||
{
|
||||
@@ -4525,7 +4552,8 @@ WifiPhy::SwitchMaybeToCcaBusy (void)
|
||||
//In this model, CCA becomes busy when the aggregation of all signals as
|
||||
//tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
|
||||
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW);
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaEdThresholdW, GetBand (primaryChannelWidth));
|
||||
if (!delayUntilCcaEnd.IsZero ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
|
||||
@@ -4592,8 +4620,11 @@ WifiPhy::GetTxPowerForTransmission (WifiTxVector txVector) const
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::StartRx (Ptr<Event> event, double rxPowerW)
|
||||
WifiPhy::StartRx (Ptr<Event> event)
|
||||
{
|
||||
uint16_t primaryChannelWidth = GetChannelWidth () >= 40 ? 20 : GetChannelWidth ();
|
||||
auto primaryBand = GetBand (primaryChannelWidth);
|
||||
double rxPowerW = event->GetRxPowerW (primaryBand);
|
||||
NS_LOG_FUNCTION (this << *event << rxPowerW);
|
||||
|
||||
NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
|
||||
@@ -4605,7 +4636,7 @@ WifiPhy::StartRx (Ptr<Event> event, double rxPowerW)
|
||||
Time remainingRxDuration = event->GetDuration () - startOfPreambleDuration;
|
||||
m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, event);
|
||||
}
|
||||
else if ((m_frameCaptureModel != 0) && (rxPowerW > m_currentEvent->GetRxPowerW ()))
|
||||
else if ((m_frameCaptureModel != 0) && (rxPowerW > m_currentEvent->GetRxPowerW (primaryBand)))
|
||||
{
|
||||
NS_LOG_DEBUG ("Received a stronger signal during preamble detection: drop current packet and switch to new packet");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (m_currentEvent->GetPpdu ()), PREAMBLE_DETECTION_PACKET_SWITCH);
|
||||
@@ -4668,6 +4699,15 @@ WifiPhy::GetStaId (void) const
|
||||
return SU_STA_ID;
|
||||
}
|
||||
|
||||
WifiSpectrumBand
|
||||
WifiPhy::GetBand (uint16_t /*bandWidth*/, uint8_t /*bandIndex*/)
|
||||
{
|
||||
WifiSpectrumBand band;
|
||||
band.first = 0;
|
||||
band.second = 0;
|
||||
return band;
|
||||
}
|
||||
|
||||
int64_t
|
||||
WifiPhy::AssignStreams (int64_t stream)
|
||||
{
|
||||
|
||||
@@ -153,6 +153,19 @@ public:
|
||||
WifiPhy ();
|
||||
virtual ~WifiPhy ();
|
||||
|
||||
/**
|
||||
* A pair of a channel number and a WifiPhyBand
|
||||
*/
|
||||
typedef std::pair<uint8_t, WifiPhyBand> ChannelNumberBandPair;
|
||||
/**
|
||||
* A pair of a ChannelNumberBandPair and a WifiPhyStandard
|
||||
*/
|
||||
typedef std::pair<ChannelNumberBandPair, WifiPhyStandard> ChannelNumberStandardPair;
|
||||
/**
|
||||
* A pair of a center frequency (MHz) and a channel width (MHz)
|
||||
*/
|
||||
typedef std::pair<uint16_t, uint16_t> FrequencyWidthPair;
|
||||
|
||||
/**
|
||||
* Return the WifiPhyStateHelper of this PHY
|
||||
*
|
||||
@@ -195,9 +208,9 @@ public:
|
||||
* Start receiving the PHY preamble of a PPDU (i.e. the first bit of the preamble has arrived).
|
||||
*
|
||||
* \param ppdu the arriving PPDU
|
||||
* \param rxPowerW the receive power in W
|
||||
* \param rxPowersW the receive power in W per 20 MHz channel band
|
||||
*/
|
||||
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, double rxPowerW);
|
||||
void StartReceivePreamble (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand rxPowersW);
|
||||
|
||||
/**
|
||||
* Start receiving the PHY header of a PPDU (i.e. after the end of receiving the preamble).
|
||||
@@ -223,7 +236,7 @@ public:
|
||||
/**
|
||||
* The last symbol of the PPDU has arrived.
|
||||
*
|
||||
* \param event the corresponding event of the first time the packet arrives (also storing packet and TxVector information)
|
||||
* \param event the event holding incoming PPDU's information
|
||||
*/
|
||||
void EndReceive (Ptr<Event> event);
|
||||
|
||||
@@ -730,19 +743,6 @@ public:
|
||||
*/
|
||||
bool DefineChannelNumber (uint8_t channelNumber, WifiPhyBand band, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth);
|
||||
|
||||
/**
|
||||
* A pair of a channel number and a WifiPhyBand
|
||||
*/
|
||||
typedef std::pair<uint8_t, WifiPhyBand> ChannelNumberBandPair;
|
||||
/**
|
||||
* A pair of a ChannelNumberBandPair and a WifiPhyStandard
|
||||
*/
|
||||
typedef std::pair<ChannelNumberBandPair, WifiPhyStandard> ChannelNumberStandardPair;
|
||||
/**
|
||||
* A pair of a center frequency (MHz) and a channel width (MHz)
|
||||
*/
|
||||
typedef std::pair<uint16_t, uint16_t> FrequencyWidthPair;
|
||||
|
||||
/**
|
||||
* Return the Channel this WifiPhy is connected to.
|
||||
*
|
||||
@@ -1771,6 +1771,16 @@ protected:
|
||||
*/
|
||||
virtual uint16_t GetStaId (void) const;
|
||||
|
||||
/**
|
||||
* Get the start band index and the stop band index for a given band
|
||||
*
|
||||
* \param bandWidth the width of the band to be returned (MHz)
|
||||
* \param bandIndex the index of the band to be returned
|
||||
*
|
||||
* \return a pair of start and stop indexes that defines the band
|
||||
*/
|
||||
virtual WifiSpectrumBand GetBand (uint16_t bandWidth, uint8_t bandIndex = 0);
|
||||
|
||||
InterferenceHelper m_interference; //!< Pointer to InterferenceHelper
|
||||
Ptr<UniformRandomVariable> m_random; //!< Provides uniform random variables.
|
||||
Ptr<WifiPhyStateHelper> m_state; //!< Pointer to WifiPhyStateHelper
|
||||
@@ -1897,9 +1907,8 @@ private:
|
||||
* Starting receiving the PPDU after having detected the medium is idle or after a reception switch.
|
||||
*
|
||||
* \param event the event holding incoming PPDU's information
|
||||
* \param rxPowerW the receive power in W
|
||||
*/
|
||||
void StartRx (Ptr<Event> event, double rxPowerW);
|
||||
void StartRx (Ptr<Event> event);
|
||||
/**
|
||||
* Get the reception status for the provided MPDU and notify.
|
||||
*
|
||||
|
||||
@@ -377,6 +377,11 @@ WifiTxVector::GetHeMuUserInfoMap (void) const
|
||||
|
||||
std::ostream & operator << ( std::ostream &os, const WifiTxVector &v)
|
||||
{
|
||||
if (!v.IsValid ())
|
||||
{
|
||||
os << "TXVECTOR not valid";
|
||||
return os;
|
||||
}
|
||||
os << "txpwrlvl: " << +v.GetTxPowerLevel ()
|
||||
<< " preamble: " << v.GetPreambleType ()
|
||||
<< " channel width: " << v.GetChannelWidth ()
|
||||
|
||||
@@ -133,7 +133,9 @@ YansWifiChannel::Receive (Ptr<YansWifiPhy> phy, Ptr<WifiPpdu> ppdu, double rxPow
|
||||
NS_LOG_INFO ("Received signal too weak to process: " << rxPowerDbm << " dBm");
|
||||
return;
|
||||
}
|
||||
phy->StartReceivePreamble (ppdu, DbmToW (rxPowerDbm + phy->GetRxGain ()));
|
||||
RxPowerWattPerChannelBand rxPowerW;
|
||||
rxPowerW.insert ({std::make_pair (0, 0), (DbmToW (rxPowerDbm + phy->GetRxGain ()))}); //dummy band for YANS
|
||||
phy->StartReceivePreamble (ppdu, rxPowerW);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
|
||||
@@ -45,6 +45,11 @@ YansWifiPhy::GetTypeId (void)
|
||||
YansWifiPhy::YansWifiPhy ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
//add dummy band for Yans
|
||||
WifiSpectrumBand band;
|
||||
band.first = 0;
|
||||
band.second = 0;
|
||||
m_interference.AddBand (band);
|
||||
}
|
||||
|
||||
YansWifiPhy::~YansWifiPhy ()
|
||||
|
||||
@@ -515,7 +515,7 @@ TestInterBssConstantObssPdAlgo::DoRun (void)
|
||||
m_bssColor3 = 3;
|
||||
RunOne ();
|
||||
|
||||
//Test case 3: CCA CS Threshold = < m_obssPdLevelDbm = m_obssRxPowerDbm
|
||||
//Test case 3: CCA CS Threshold < m_obssPdLevelDbm = m_obssRxPowerDbm
|
||||
m_obssPdLevelDbm = -72;
|
||||
m_obssRxPowerDbm = -72;
|
||||
m_bssColor1 = 1;
|
||||
|
||||
@@ -245,7 +245,7 @@ WifiTransmitMaskTestSuite::WifiTransmitMaskTestSuite ()
|
||||
: TestSuite ("wifi-transmit-mask", UNIT)
|
||||
{
|
||||
// LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
|
||||
// LogComponentEnable ("WifiTransmitMaskTestSuite", logLevel);
|
||||
// LogComponentEnable ("WifiTransmitMaskTest", logLevel);
|
||||
// LogComponentEnable ("WifiSpectrumValueHelper", logLevel);
|
||||
|
||||
NS_LOG_INFO ("Creating WifiTransmitMaskTestSuite");
|
||||
|
||||
Reference in New Issue
Block a user