Files
unison/src/wifi/model/interference-helper.h

542 lines
18 KiB
C++

/*
* Copyright (c) 2005,2006 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef INTERFERENCE_HELPER_H
#define INTERFERENCE_HELPER_H
#include "phy-entity.h"
#include "ns3/object.h"
namespace ns3
{
class WifiPpdu;
class WifiPsdu;
class ErrorRateModel;
/**
* \ingroup wifi
* \brief handles interference calculations
* \brief signal event for a PPDU.
*/
class Event : public SimpleRefCount<Event>
{
public:
/**
* Create an Event with the given parameters. Note that <i>rxPower</i> will
* be moved into this object.
*
* \param ppdu the PPDU
* \param txVector the TXVECTOR
* \param duration duration of the PPDU
* \param rxPower the received power per band (W)
*/
Event(Ptr<const WifiPpdu> ppdu,
const WifiTxVector& txVector,
Time duration,
RxPowerWattPerChannelBand&& rxPower);
~Event();
/**
* Return the PPDU.
*
* \return the PPDU
*/
Ptr<const WifiPpdu> GetPpdu() const;
/**
* Return the start time of the signal.
*
* \return the start time of the signal
*/
Time GetStartTime() const;
/**
* Return the end time of the signal.
*
* \return the end time of the signal
*/
Time GetEndTime() const;
/**
* Return the duration of the signal.
*
* \return the duration of the signal
*/
Time GetDuration() const;
/**
* Return the total received power (W).
*
* \return the total received power (W)
*/
double GetRxPowerW() 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(const WifiSpectrumBandInfo& band) const;
/**
* Return the received power (W) for all bands.
*
* \return the received power (W) for all bands.
*/
const RxPowerWattPerChannelBand& GetRxPowerWPerBand() const;
/**
* Return the TXVECTOR of the PPDU.
*
* \return the TXVECTOR of the PPDU
*/
const WifiTxVector& GetTxVector() const;
/**
* Update the received power (W) for all bands, i.e. add up the received power
* to the current received power, for each band.
*
* \param rxPower the received power (W) for all bands.
*/
void UpdateRxPowerW(const RxPowerWattPerChannelBand& rxPower);
private:
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
};
/**
* \brief Stream insertion operator.
*
* \param os the stream
* \param event the event
* \returns a reference to the stream
*/
std::ostream& operator<<(std::ostream& os, const Event& event);
/**
* \ingroup wifi
* \brief handles interference calculations
*/
class InterferenceHelper : public Object
{
public:
InterferenceHelper();
~InterferenceHelper() override;
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
/**
* Add a frequency band.
*
* \param band the band to be added
*/
void AddBand(const WifiSpectrumBandInfo& band);
/**
* Check whether bands are already tracked by this interference helper.
*
* \return true if bands are tracked by this interference helper, false otherwise
*/
bool HasBands() const;
/**
* Update the frequency bands that belongs to a given frequency range when the spectrum model is
* changed.
*
* \param bands the bands to be added in the new spectrum model
* \param freqRange the frequency range the bands belong to
*/
void UpdateBands(const std::vector<WifiSpectrumBandInfo>& bands,
const FrequencyRange& freqRange);
/**
* Set the noise figure.
*
* \param value noise figure in linear scale
*/
void SetNoiseFigure(double value);
/**
* Set the error rate model for this interference helper.
*
* \param rate Error rate model
*/
void SetErrorRateModel(const Ptr<ErrorRateModel> rate);
/**
* Return the error rate model.
*
* \return Error rate model
*/
Ptr<ErrorRateModel> GetErrorRateModel() const;
/**
* Set the number of RX antennas in the receiver corresponding to this
* interference helper.
*
* \param rx the number of RX antennas
*/
void SetNumberOfReceiveAntennas(uint8_t rx);
/**
* \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 for a given band will
* be higher than the requested threshold.
*/
Time GetEnergyDuration(double energyW, const WifiSpectrumBandInfo& band);
/**
* Add the PPDU-related signal to interference helper.
*
* \param ppdu the PPDU
* \param txVector the TXVECTOR
* \param duration the PPDU duration
* \param rxPower received power per band (W)
* \param isStartHePortionRxing flag whether the event corresponds to the start of the HE
* portion reception (only used for MU)
*
* \return Event
*/
Ptr<Event> Add(Ptr<const WifiPpdu> ppdu,
const WifiTxVector& txVector,
Time duration,
RxPowerWattPerChannelBand& rxPower,
bool isStartHePortionRxing = false);
/**
* Add a non-Wifi signal to interference helper.
* \param duration the duration of the signal
* \param rxPower received power per band (W)
*/
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.
* This workaround is required in order to provide one PER per MPDU, for
* reception success/failure evaluation, while hiding aggregation details from
* 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)
*/
PhyEntity::SnrPer CalculatePayloadSnrPer(Ptr<Event> event,
uint16_t channelWidth,
const WifiSpectrumBandInfo& 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,
uint16_t channelWidth,
uint8_t nss,
const WifiSpectrumBandInfo& band) const;
/**
* Calculate the SNIR at the start of the 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 channelWidth the channel width (in MHz) for header measurement
* \param band identify the band used by the PSDU
* \param header the PHY header to consider
*
* \return struct of SNR and PER
*/
PhyEntity::SnrPer CalculatePhyHeaderSnrPer(Ptr<Event> event,
uint16_t channelWidth,
const WifiSpectrumBandInfo& band,
WifiPpduField header) const;
/**
* Notify that RX has started.
*/
void NotifyRxStart();
/**
* Notify that RX has ended.
*
* \param endTime the end time of the signal
* \param freqRange the frequency range in which the received signal event had been detected
*/
void NotifyRxEnd(Time endTime, const FrequencyRange& freqRange);
/**
* Update event to scale its received power (W) per band.
*
* \param event the event to be updated
* \param rxPower the received power (W) per band to be added to the current event
*/
void UpdateEvent(Ptr<Event> event, const RxPowerWattPerChannelBand& rxPower);
protected:
void DoDispose() override;
/**
* Calculate SNR (linear ratio) from the given signal power and noise+interference power.
*
* \param signal signal power, W
* \param noiseInterference noise and interference power, W
* \param channelWidth signal width (MHz)
* \param nss the number of spatial streams
*
* \return SNR in linear scale
*/
double CalculateSnr(double signal,
double noiseInterference,
uint16_t channelWidth,
uint8_t nss) const;
/**
* Calculate the success rate of the chunk given the SINR, duration, and TXVECTOR.
* The duration and TXVECTOR are used to calculate how many bits are present in the chunk.
*
* \param snir the SINR
* \param duration the duration of the chunk
* \param mode the WifiMode
* \param txVector the TXVECTOR
* \param field the PPDU field to which the chunk belongs to
*
* \return the success rate
*/
double CalculateChunkSuccessRate(double snir,
Time duration,
WifiMode mode,
const WifiTxVector& txVector,
WifiPpduField field) const;
/**
* Calculate the success rate of the payload chunk given the SINR, duration, and TXVECTOR.
* The duration and TXVECTOR are used to calculate how many bits are present in the payload
* chunk.
*
* \param snir the SINR
* \param duration the duration of the chunk
* \param txVector the TXVECTOR
* \param staId the station ID of the PSDU (only used for MU)
*
* \return the success rate
*/
double CalculatePayloadChunkSuccessRate(double snir,
Time duration,
const WifiTxVector& txVector,
uint16_t staId = SU_STA_ID) const;
private:
/**
* Noise and Interference (thus Ni) event.
*/
class NiChange
{
public:
/**
* Create a NiChange at the given time and the amount of NI change.
*
* \param power the power in watts
* \param event causes this NI change
*/
NiChange(double power, Ptr<Event> event);
~NiChange();
/**
* Return the power
*
* \return the power in watts
*/
double GetPower() const;
/**
* Add a given amount of power.
*
* \param power the power to be added to the existing value in watts
*/
void AddPower(double power);
/**
* Return the event causes the corresponding NI change
*
* \return the event
*/
Ptr<Event> GetEvent() const;
private:
double m_power; ///< power in watts
Ptr<Event> m_event; ///< event
};
/**
* typedef for a multimap of NiChange
*/
using NiChanges = std::multimap<Time, NiChange>;
/**
* Map of NiChanges per band
*/
using NiChangesPerBand = std::map<WifiSpectrumBandInfo, NiChanges>;
/**
* Map of first power per band
*/
using FirstPowerPerBand = std::map<WifiSpectrumBandInfo, double>;
/**
* Check whether a given band is tracked by this interference helper.
*
* \param band the band to be checked
* \return true if the band is already tracked by this interference helper, false otherwise
*/
bool HasBand(const WifiSpectrumBandInfo& band) const;
/**
* Check whether a given band belongs to a given frequency range.
*
* \param band the band to be checked
* \param freqRange the frequency range to check whether the band belong to
* \return true if the band belongs to the frequency range, false otherwise
*/
bool IsBandInFrequencyRange(const WifiSpectrumBandInfo& band,
const FrequencyRange& freqRange) const;
/**
* Append the given Event.
*
* \param event the event to be appended
* \param isStartHePortionRxing flag whether event corresponds to the start of the HE portion
* reception (only used for MU)
*/
void AppendEvent(Ptr<Event> event, bool isStartHePortionRxing);
/**
* Calculate noise and interference power in W.
*
* \param event the event
* \param nis the NiChanges
* \param band the band
*
* \return noise and interference power
*/
double CalculateNoiseInterferenceW(Ptr<Event> event,
NiChangesPerBand* nis,
const WifiSpectrumBandInfo& band) const;
/**
* Calculate the error rate of the given PHY payload only in the provided time
* window (thus enabling per MPDU PER information). The PHY payload can be divided into
* multiple chunks (e.g. due to interference from other transmissions).
*
* \param event the event
* \param channelWidth the channel width used to transmit the PSDU (in MHz)
* \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 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 channelWidth,
NiChangesPerBand* nis,
const WifiSpectrumBandInfo& band,
uint16_t staId,
std::pair<Time, Time> window) const;
/**
* Calculate the error rate of the PHY header. The PHY header
* can be divided into multiple chunks (e.g. due to interference from other transmissions).
*
* \param event the event
* \param nis the NiChanges
* \param channelWidth the channel width (in MHz) for header measurement
* \param band the band
* \param header the PHY header to consider
*
* \return the error rate of the HT PHY header
*/
double CalculatePhyHeaderPer(Ptr<const Event> event,
NiChangesPerBand* nis,
uint16_t channelWidth,
const WifiSpectrumBandInfo& band,
WifiPpduField header) const;
/**
* Calculate the success rate of the PHY header sections for the provided event.
*
* \param event the event
* \param nis the NiChanges
* \param channelWidth the channel width (in MHz) for header measurement
* \param band the band
* \param phyHeaderSections the map of PHY header sections (\see PhyEntity::PhyHeaderSections)
*
* \return the success rate of the PHY header sections
*/
double CalculatePhyHeaderSectionPsr(Ptr<const Event> event,
NiChangesPerBand* nis,
uint16_t channelWidth,
const WifiSpectrumBandInfo& band,
PhyEntity::PhyHeaderSections phyHeaderSections) 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
NiChangesPerBand m_niChanges; //!< NI Changes for each band
FirstPowerPerBand m_firstPowers; //!< 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 niIt iterator of the band to check
* \returns an iterator to the list of NiChanges
*/
NiChanges::iterator GetNextPosition(Time moment, NiChangesPerBand::iterator niIt);
/**
* Returns an iterator to the last NiChange that is before than moment
*
* \param moment time to check from
* \param niIt iterator of the band to check
* \returns an iterator to the list of NiChanges
*/
NiChanges::iterator GetPreviousPosition(Time moment, NiChangesPerBand::iterator niIt);
/**
* Add NiChange to the list at the appropriate position and
* return the iterator of the new event.
*
* \param moment time to check from
* \param change the NiChange to add
* \param niIt iterator of the band to check
* \returns the iterator of the new event
*/
NiChanges::iterator AddNiChangeEvent(Time moment,
NiChange change,
NiChangesPerBand::iterator niIt);
};
} // namespace ns3
#endif /* INTERFERENCE_HELPER_H */