33 #include "ns3/boolean.h"
34 #include "ns3/double.h"
37 #include "ns3/simulator.h"
38 #include "ns3/wifi-net-device.h"
51 TypeId(
"ns3::SpectrumWifiPhy")
55 .AddAttribute(
"DisableWifiReception",
56 "Prevent Wi-Fi frame sync from ever happening",
61 "TxMaskInnerBandMinimumRejection",
62 "Minimum rejection (dBr) for the inner band of the transmit spectrum mask",
65 MakeDoubleChecker<double>())
67 "TxMaskOuterBandMinimumRejection",
68 "Minimum rejection (dBr) for the outer band of the transmit spectrum mask",
71 MakeDoubleChecker<double>())
73 "TxMaskOuterBandMaximumRejection",
74 "Maximum rejection (dBr) for the outer band of the transmit spectrum mask",
77 MakeDoubleChecker<double>())
78 .AddTraceSource(
"SignalArrival",
81 "ns3::SpectrumWifiPhy::SignalArrivalCallback");
119 NS_FATAL_ERROR(
"SpectrumWifiPhy misses channel and WifiSpectrumPhyInterface objects at "
120 "initialization time");
142 NS_LOG_DEBUG(
"Creating spectrum model from frequency/width pair of ("
161 if (channelWidth < 20)
168 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
170 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
186 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
188 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
194 for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++)
199 std::make_pair(group.front().first, group.back().second);
206 (bw == 160 && phyIndex > nRus / 2 ? phyIndex - nRus / 2 : phyIndex);
207 bool primary80IsLower80 =
210 (primary80IsLower80 && phyIndex <= nRus / 2) ||
211 (!primary80IsLower80 && phyIndex > nRus / 2));
216 m_ruBands[channelWidth].insert({band, ru});
222 for (
const auto& bandRuPair :
m_ruBands[channelWidth])
247 NS_LOG_DEBUG(
"Run-time change of spectrum model from frequency/width pair of ("
282 NS_LOG_DEBUG(
"Received signal with PSD " << *receivedSignalPsd <<
" and duration "
284 uint32_t senderNodeId = 0;
289 NS_LOG_DEBUG(
"Received signal from " << senderNodeId <<
" with unfiltered power "
297 double totalRxPowerW = 0;
300 if ((channelWidth == 5) || (channelWidth == 10))
303 double rxPowerPerBandW =
305 NS_LOG_DEBUG(
"Signal power received (watts) before antenna gain: " << rxPowerPerBandW);
307 totalRxPowerW += rxPowerPerBandW;
308 rxPowerW.insert({filteredBand, rxPowerPerBandW});
309 NS_LOG_DEBUG(
"Signal power received after antenna gain for "
310 << channelWidth <<
" MHz channel: " << rxPowerPerBandW <<
" W ("
311 <<
WToDbm(rxPowerPerBandW) <<
" dBm)");
315 for (uint16_t bw = 160; bw > 20; bw = bw / 2)
317 for (uint32_t i = 0; i < (channelWidth / bw); i++)
321 double rxPowerPerBandW =
323 NS_LOG_DEBUG(
"Signal power received (watts) before antenna gain for "
324 << bw <<
" MHz channel band " << +i <<
": " << rxPowerPerBandW);
326 rxPowerW.insert({filteredBand, rxPowerPerBandW});
327 NS_LOG_DEBUG(
"Signal power received after antenna gain for "
328 << bw <<
" MHz channel band " << +i <<
": " << rxPowerPerBandW <<
" W ("
329 <<
WToDbm(rxPowerPerBandW) <<
" dBm)");
333 for (uint32_t i = 0; i < (channelWidth / 20); i++)
336 double rxPowerPerBandW =
338 NS_LOG_DEBUG(
"Signal power received (watts) before antenna gain for 20 MHz channel band "
339 << +i <<
": " << rxPowerPerBandW);
341 totalRxPowerW += rxPowerPerBandW;
342 rxPowerW.insert({filteredBand, rxPowerPerBandW});
343 NS_LOG_DEBUG(
"Signal power received after antenna gain for 20 MHz channel band "
344 << +i <<
": " << rxPowerPerBandW <<
" W (" <<
WToDbm(rxPowerPerBandW)
351 for (
const auto& bandRuPair :
m_ruBands[channelWidth])
353 double rxPowerPerBandW =
355 NS_LOG_DEBUG(
"Signal power received (watts) before antenna gain for RU with type "
356 << bandRuPair.second.GetRuType() <<
" and index "
357 << bandRuPair.second.GetIndex() <<
" -> (" << bandRuPair.first.first
358 <<
"; " << bandRuPair.first.second <<
"): " << rxPowerPerBandW);
360 NS_LOG_DEBUG(
"Signal power received after antenna gain for RU with type "
361 << bandRuPair.second.GetRuType() <<
" and index "
362 << bandRuPair.second.GetIndex() <<
" -> (" << bandRuPair.first.first
363 <<
"; " << bandRuPair.first.second <<
"): " << rxPowerPerBandW <<
" W ("
364 <<
WToDbm(rxPowerPerBandW) <<
" dBm)");
365 rxPowerW.insert({bandRuPair.first, rxPowerPerBandW});
369 NS_LOG_DEBUG(
"Total signal power received after antenna gain: "
370 << totalRxPowerW <<
" W (" <<
WToDbm(totalRxPowerW) <<
" dBm)");
373 DynamicCast<WifiSpectrumSignalParameters>(rxParams);
376 m_signalCb(
bool(wifiRxParams), senderNodeId,
WToDbm(totalRxPowerW), rxDuration);
387 NS_LOG_INFO(
"Received Wi-Fi signal but blocked from syncing");
395 const auto txWidth = wifiRxParams->txWidth;
397 const auto& txVector = ppdu->GetTxVector();
400 NS_LOG_INFO(
"Received signal too weak to process: " <<
WToDbm(totalRxPowerW) <<
" dBm");
406 if (wifiRxParams->txPhy)
410 NS_LOG_INFO(
"Cannot start reception of the PPDU, consider it as interference");
463 "SpectrumPhy() is not set; maybe forgot to call CreateWifiSpectrumPhyInterface?");
473 uint32_t bandBandwidth = 0;
482 bandBandwidth = 312500;
488 bandBandwidth = 78125;
493 bandBandwidth = 156250;
499 bandBandwidth = 78125;
505 return bandBandwidth;
511 uint16_t guardBandwidth = 0;
512 if (currentChannelWidth == 22)
525 guardBandwidth = currentChannelWidth;
527 return guardBandwidth;
535 size_t numBandsInChannel =
static_cast<size_t>(channelWidth * 1e6 / bandBandwidth);
536 size_t numBandsInBand =
static_cast<size_t>(bandWidth * 1e6 / bandBandwidth);
537 if (numBandsInBand % 2 == 0)
539 numBandsInChannel += 1;
542 NS_ASSERT_MSG((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1),
543 "Should have odd number of bands");
544 NS_ASSERT_MSG((bandIndex * bandWidth) < channelWidth,
"Band index is out of bound");
546 band.first = ((totalNumBands - numBandsInChannel) / 2) + (bandIndex * numBandsInBand);
547 band.second = band.first + numBandsInBand - 1;
548 if (band.first >= totalNumBands / 2)
558 uint16_t guardBandwidth,
560 uint8_t bandIndex)
const
563 uint32_t nGuardBands =
564 static_cast<uint32_t
>(((2 * guardBandwidth * 1e6) /
GetBandBandwidth()) + 0.5);
565 uint32_t centerFrequencyIndex = 0;
569 centerFrequencyIndex = (nGuardBands / 2) + 6 + 122;
572 centerFrequencyIndex = (nGuardBands / 2) + 12 + 244;
575 centerFrequencyIndex = (nGuardBands / 2) + 12 + 500;
578 centerFrequencyIndex = (nGuardBands / 2) + 12 + 1012;
585 size_t numBandsInBand =
static_cast<size_t>(bandWidth * 1e6 /
GetBandBandwidth());
586 centerFrequencyIndex += numBandsInBand * bandIndex;
588 convertedSubcarriers.first = centerFrequencyIndex + range.first;
589 convertedSubcarriers.second = centerFrequencyIndex + range.second;
590 return convertedSubcarriers;
593 std::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'.
std::size_t GetPhyIndex(uint16_t bw, uint8_t p20Index) 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.
bool IsInitialized() const
Check if the object has been initialized.
size_t GetNumBands() const
Abstract base class for Spectrum-aware PHY layers.
virtual Ptr< NetDevice > GetDevice() const =0
Get the associated NetDevice instance.
~SpectrumWifiPhy() override
TracedCallback< bool, uint32_t, double, Time > m_signalCb
Signal callback.
std::tuple< double, double, double > GetTxMaskRejectionParams() const override
bool CanStartRx(Ptr< const WifiPpdu > ppdu, uint16_t txChannelWidth) const
Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a given PPDU.
void Transmit(Ptr< WifiSpectrumSignalParameters > txParams)
This function is sending the signal to the Spectrum channel after finishing the configuration of the ...
void DoInitialize() override
Initialize() implementation.
Ptr< SpectrumChannel > m_channel
SpectrumChannel that this SpectrumWifiPhy is connected to.
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...
Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu)
Determine the WifiPpdu to be used by the RX PHY based on the WifiPpdu sent by the TX PHY.
void ResetSpectrumModel()
Perform run-time spectrum model change.
Ptr< Channel > GetChannel() const override
Return the Channel this WifiPhy is connected to.
void SetChannel(const Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
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.
void DoDispose() override
Destructor implementation.
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const override
uint32_t GetBandBandwidth() const
static TypeId GetTypeId()
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
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.
Ptr< Object > GetAntenna() const
Get the antenna model used for reception.
void UpdateInterferenceHelperBands()
This function is called to update the bands handled by the InterferenceHelper.
Ptr< const SpectrumModel > m_rxSpectrumModel
receive spectrum model
void StartTx(Ptr< const WifiPpdu > ppdu) override
void DoChannelSwitch() override
Actually switch channel based on the stored channel settings.
void StartRx(Ptr< SpectrumSignalParameters > rxParams)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
void CreateWifiSpectrumPhyInterface(Ptr< NetDevice > device)
Method to encapsulate the creation of the WifiSpectrumPhyInterface object (used to bind the WifiSpect...
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const 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.
uint16_t GetChannelWidth() const
double GetRxSensitivity() const
Return the receive sensitivity threshold (dBm).
uint16_t GetFrequency() const
double GetRxGain() const
Return the reception gain (dB).
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
void DoDispose() override
Destructor implementation.
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
void DoInitialize() override
Initialize() implementation.
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
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...
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.
#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 AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#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.
Time duration
The duration of the packet transmission.
Ptr< SpectrumPhy > txPhy
The SpectrumPhy instance that is making the transmission.
Ptr< SpectrumValue > psd
The Power Spectral Density of the waveform, in linear units.