27#include "ns3/double.h"
28#include "ns3/boolean.h"
29#include "ns3/wifi-net-device.h"
31#include "ns3/simulator.h"
49 .SetGroupName (
"Wifi")
51 .AddAttribute (
"DisableWifiReception",
52 "Prevent Wi-Fi frame sync from ever happening",
56 .AddAttribute (
"TxMaskInnerBandMinimumRejection",
57 "Minimum rejection (dBr) for the inner band of the transmit spectrum mask",
60 MakeDoubleChecker<double> ())
61 .AddAttribute (
"TxMaskOuterBandMinimumRejection",
62 "Minimum rejection (dBr) for the outer band of the transmit spectrum mask",
65 MakeDoubleChecker<double> ())
66 .AddAttribute (
"TxMaskOuterBandMaximumRejection",
67 "Maximum rejection (dBr) for the outer band of the transmit spectrum mask",
70 MakeDoubleChecker<double> ())
71 .AddTraceSource (
"SignalArrival",
74 "ns3::SpectrumWifiPhy::SignalArrivalCallback")
113 NS_FATAL_ERROR (
"SpectrumWifiPhy misses channel and WifiSpectrumPhyInterface objects at initialization time");
135 NS_LOG_DEBUG (
"Creating spectrum model from frequency/width pair of (" <<
GetFrequency () <<
", " << channelWidth <<
")");
149 if (channelWidth < 20)
156 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
158 for (uint8_t i = 0; i < (channelWidth / bw); ++i)
174 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
176 for (uint8_t i = 0; i < (channelWidth / bw); ++i)
178 for (
unsigned int type = 0; type < 7; type++)
182 for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++)
188 std::size_t index = (bw == 160 && phyIndex > nRus / 2
189 ? phyIndex - nRus / 2 : phyIndex);
192 bool primary80 = (bw < 160
194 || (primary80IsLower80 && phyIndex <= nRus / 2)
195 || (!primary80IsLower80 && phyIndex > nRus / 2));
199 m_ruBands[channelWidth].insert ({band, ru});
205 for (
const auto& bandRuPair :
m_ruBands[channelWidth])
230 NS_LOG_DEBUG (
"Run-time change of spectrum model from frequency/width pair of (" <<
GetFrequency () <<
", " << channelWidth <<
")");
253 Time rxDuration = rxParams->duration;
255 NS_LOG_DEBUG (
"Received signal with PSD " << *receivedSignalPsd <<
" and duration " << rxDuration.
As (
Time::NS));
259 senderNodeId = rxParams->txPhy->GetDevice ()->GetNode ()->GetId ();
261 NS_LOG_DEBUG (
"Received signal from " << senderNodeId <<
" with unfiltered power " <<
WToDbm (
Integral (*receivedSignalPsd)) <<
" dBm");
268 double totalRxPowerW = 0;
271 if ((channelWidth == 5) || (channelWidth == 10))
275 NS_LOG_DEBUG (
"Signal power received (watts) before antenna gain: " << rxPowerPerBandW);
277 totalRxPowerW += rxPowerPerBandW;
278 rxPowerW.insert ({filteredBand, rxPowerPerBandW});
279 NS_LOG_DEBUG (
"Signal power received after antenna gain for " << channelWidth <<
" MHz channel: " << rxPowerPerBandW <<
" W (" <<
WToDbm (rxPowerPerBandW) <<
" dBm)");
282 for (uint16_t bw = 160; bw > 20; bw = bw / 2)
284 for (uint8_t i = 0; i < (channelWidth / bw); i++)
289 NS_LOG_DEBUG (
"Signal power received (watts) before antenna gain for " << bw <<
" MHz channel band " << +i <<
": " << rxPowerPerBandW);
291 rxPowerW.insert ({filteredBand, rxPowerPerBandW});
292 NS_LOG_DEBUG (
"Signal power received after antenna gain for " << bw <<
" MHz channel band " << +i <<
": " << rxPowerPerBandW <<
" W (" <<
WToDbm (rxPowerPerBandW) <<
" dBm)");
297 for (uint8_t i = 0; i < (channelWidth / 20); i++)
301 NS_LOG_DEBUG (
"Signal power received (watts) before antenna gain for 20 MHz channel band " << +i <<
": " << rxPowerPerBandW);
303 totalRxPowerW += rxPowerPerBandW;
304 rxPowerW.insert ({filteredBand, rxPowerPerBandW});
305 NS_LOG_DEBUG (
"Signal power received after antenna gain for 20 MHz channel band " << +i <<
": " << rxPowerPerBandW <<
" W (" <<
WToDbm (rxPowerPerBandW) <<
" dBm)");
311 for (
const auto& bandRuPair :
m_ruBands[channelWidth])
314 NS_LOG_DEBUG (
"Signal power received (watts) before antenna gain for RU with type " << bandRuPair.second.GetRuType () <<
" and index " << bandRuPair.second.GetIndex () <<
" -> (" << bandRuPair.first.first <<
"; " << bandRuPair.first.second <<
"): " << rxPowerPerBandW);
316 NS_LOG_DEBUG (
"Signal power received after antenna gain for RU with type " << bandRuPair.second.GetRuType () <<
" and index " << bandRuPair.second.GetIndex () <<
" -> (" << bandRuPair.first.first <<
"; " << bandRuPair.first.second <<
"): " << rxPowerPerBandW <<
" W (" <<
WToDbm (rxPowerPerBandW) <<
" dBm)");
317 rxPowerW.insert ({bandRuPair.first, rxPowerPerBandW});
321 NS_LOG_DEBUG (
"Total signal power received after antenna gain: " << totalRxPowerW <<
" W (" <<
WToDbm (totalRxPowerW) <<
" dBm)");
326 m_signalCb (wifiRxParams, senderNodeId,
WToDbm (totalRxPowerW), rxDuration);
328 if (wifiRxParams == 0)
337 NS_LOG_INFO (
"Received Wi-Fi signal but blocked from syncing");
345 uint16_t txWidth = wifiRxParams->ppdu->GetTransmissionChannelWidth ();
348 NS_LOG_INFO (
"Received signal too weak to process: " <<
WToDbm (totalRxPowerW) <<
" dBm");
349 m_interference.
Add (wifiRxParams->ppdu, wifiRxParams->ppdu->GetTxVector (), rxDuration,
357 if (wifiRxParams->txPhy != 0)
361 uint16_t p20MinFreq =
363 uint16_t p20MaxFreq =
366 if (!wifiRxParams->ppdu->CanBeReceived (wifiRxParams->txCenterFreq, p20MinFreq, p20MaxFreq))
368 NS_LOG_INFO (
"Cannot receive the PPDU, consider it as interference");
370 rxDuration, rxPowerW);
435 bandBandwidth = 312500;
441 bandBandwidth = 78125;
446 bandBandwidth = 156250;
451 bandBandwidth = 78125;
457 return bandBandwidth;
463 uint16_t guardBandwidth = 0;
464 if (currentChannelWidth == 22)
477 guardBandwidth = currentChannelWidth;
479 return guardBandwidth;
487 size_t numBandsInChannel =
static_cast<size_t> (channelWidth * 1e6 / bandBandwidth);
488 size_t numBandsInBand =
static_cast<size_t> (bandWidth * 1e6 / bandBandwidth);
489 if (numBandsInBand % 2 == 0)
491 numBandsInChannel += 1;
494 NS_ASSERT_MSG ((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1),
"Should have odd number of bands");
495 NS_ASSERT_MSG ((bandIndex * bandWidth) < channelWidth,
"Band index is out of bound");
497 band.first = ((totalNumBands - numBandsInChannel) / 2) + (bandIndex * numBandsInBand);
498 if (band.first >= totalNumBands / 2)
503 band.second = band.first + numBandsInBand - 1;
517 centerFrequencyIndex = (nGuardBands / 2) + 6 + 122;
520 centerFrequencyIndex = (nGuardBands / 2) + 12 + 244;
523 centerFrequencyIndex = (nGuardBands / 2) + 12 + 500;
526 centerFrequencyIndex = (nGuardBands / 2) + 12 + 1012;
533 size_t numBandsInBand =
static_cast<size_t> (bandWidth * 1e6 /
GetBandBandwidth ());
534 centerFrequencyIndex += numBandsInBand * bandIndex;
536 convertedSubcarriers.first = centerFrequencyIndex + range.first;
537 convertedSubcarriers.second = centerFrequencyIndex + range.second;
538 return convertedSubcarriers;
541std::tuple<double, double, double>
AttributeValue implementation for Boolean.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
void SetPhyIndex(uint16_t bw, uint8_t p20Index)
Set the RU PHY index.
std::size_t GetPhyIndex(void) const
Get the RU PHY index.
static SubcarrierGroup GetSubcarrierGroup(uint16_t bw, RuType ruType, std::size_t phyIndex)
Get the subcarrier group of the RU having the given PHY index among all the RUs of the given type (nu...
static std::size_t GetNRus(uint16_t bw, RuType ruType)
Get the number of distinct RUs of the given type (number of tones) available in a HE PPDU of the give...
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
std::pair< int16_t, int16_t > SubcarrierRange
(lowest index, highest index) pair defining a subcarrier range
RuType
The different HE Resource Unit (RU) types.
void AddForeignSignal(Time duration, RxPowerWattPerChannelBand &rxPower)
Add a non-Wifi signal to interference helper.
void RemoveBands(void)
Remove the frequency bands.
Ptr< Event > Add(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand &rxPower, bool isStartOfdmaRxing=false)
Add the PPDU-related signal to interference helper.
void AddBand(WifiSpectrumBand band)
Add a frequency band.
bool IsInitialized(void) const
Check if the object has been initialized.
virtual void DoInitialize(void)
Initialize() implementation.
size_t GetNumBands() const
Abstract base class for Spectrum-aware PHY layers.
TracedCallback< bool, uint32_t, double, Time > m_signalCb
Signal callback.
void Transmit(Ptr< WifiSpectrumSignalParameters > txParams)
This function is sending the signal to the Spectrum channel after finishing the configuration of the ...
uint32_t GetBandBandwidth(void) const
Ptr< SpectrumChannel > m_channel
SpectrumChannel that this SpectrumWifiPhy is connected to.
void StartTx(Ptr< WifiPpdu > ppdu) override
Ptr< AntennaModel > m_antenna
antenna model
std::map< uint16_t, RuBand > m_ruBands
For each channel width, store all the distinct spectrum bands associated with every RU in a channel o...
void DoChannelSwitch(void) override
Actually switch channel based on the stored channel settings.
std::tuple< double, double, double > GetTxMaskRejectionParams(void) const override
void SetChannel(const Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
void DoDispose(void) override
Destructor implementation.
Ptr< WifiSpectrumPhyInterface > m_wifiSpectrumPhyInterface
Spectrum PHY interface.
double m_txMaskInnerBandMinimumRejection
The minimum rejection (in dBr) for the inner band of the transmit spectrum mask.
double m_txMaskOuterBandMinimumRejection
The minimum rejection (in dBr) for the outer band of the transmit spectrum mask.
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const override
static TypeId GetTypeId(void)
Get the type ID.
void SetAntenna(const Ptr< AntennaModel > antenna)
double m_txMaskOuterBandMaximumRejection
The maximum rejection (in dBr) for the outer band of the transmit spectrum mask.
WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, HeRu::SubcarrierRange range, uint8_t bandIndex=0) const override
Ptr< Object > GetAntenna(void) const
Get the antenna model used for reception.
bool m_disableWifiReception
forces this PHY to fail to sync on any signal
Ptr< const SpectrumModel > GetRxSpectrumModel()
WifiSpectrumBand GetBand(uint16_t bandWidth, uint8_t bandIndex=0) override
Get the start band index and the stop band index for a given band.
void ResetSpectrumModel(void)
Perform run-time spectrum model change.
Ptr< const SpectrumModel > m_rxSpectrumModel
receive spectrum model
virtual ~SpectrumWifiPhy()
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
void UpdateInterferenceHelperBands(void)
This function is called to update the bands handled by the InterferenceHelper.
Ptr< Channel > GetChannel(void) const override
Return the Channel this WifiPhy is connected to.
void CreateWifiSpectrumPhyInterface(Ptr< NetDevice > device)
Method to encapsulate the creation of the WifiSpectrumPhyInterface object (used to bind the WifiSpect...
void DoInitialize(void) override
Initialize() implementation.
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
void StartReceivePreamble(Ptr< WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
const WifiPhyOperatingChannel & GetOperatingChannel(void) const
Get a const reference to the operating channel.
WifiStandard GetStandard(void) const
Get the configured Wi-Fi standard.
virtual void DoDispose(void)
Destructor implementation.
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const
Return the channel width used to measure the RSSI.
InterferenceHelper m_interference
the class handling interference computations
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class, for the WifiPhy instance.
void SwitchMaybeToCcaBusy(uint16_t channelWidth)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
double GetRxGain(void) const
Return the reception gain (dB).
double GetRxSensitivity(void) const
Return the receive sensitivity threshold (dBm).
virtual void DoChannelSwitch(void)
Actually switch channel based on the stored channel settings.
uint16_t GetChannelWidth(void) const
uint16_t GetFrequency(void) const
uint8_t GetPrimaryChannelIndex(uint16_t primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
static Ptr< SpectrumModel > GetSpectrumModel(uint32_t centerFrequency, uint16_t channelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth)
Return a SpectrumModel instance corresponding to the center frequency and channel width.
static double GetBandPowerW(Ptr< SpectrumValue > psd, const WifiSpectrumBand &band)
Calculate the power of the specified band composed of uniformly-sized sub-bands.
make Callback use a separate empty type
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double WToDbm(double w)
Convert from Watts to dBm.
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
double Integral(const SpectrumValue &arg)
double DbmToW(double dBm)
Convert from dBm to Watts.
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
double DbToRatio(double dB)
Convert from dB to ratio.