22 #include "ns3/packet.h" 23 #include "ns3/simulator.h" 40 m_txVector (txVector),
42 m_endTime (m_startTime + duration),
141 Ptr<Event> event = Create<Event> (packet, txVector, duration, rxPowerW);
153 Add (packet, fakeTxVector, duration, rxPowerW);
188 double noiseInterferenceW = i->second.GetPower ();
190 if (noiseInterferenceW < energyW)
202 double previousPowerStart = 0;
203 double previousPowerEnd = 0;
216 for (
auto i =
first; i != last; ++i)
218 i->second.AddPower (event->GetRxPowerW ());
226 static const double BOLTZMANN = 1.3803e-23;
228 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
231 double noise = noiseFloor + noiseInterference;
232 double snr = signal / noise;
233 NS_LOG_DEBUG (
"bandwidth(MHz)=" << channelWidth <<
", signal(W)= " << signal <<
", noise(W)=" << noiseFloor <<
", interference(W)=" << noiseInterference <<
", snr=" <<
RatioToDb(snr) <<
"dB");
241 auto it =
m_niChanges.find (event->GetStartTime ());
244 noiseInterferenceW = it->second.GetPower () -
event->GetRxPowerW ();
247 for (; it !=
m_niChanges.end () && it->second.GetEvent () != event; ++it);
248 ni->emplace (event->GetStartTime (),
NiChange (0, event));
249 while (++it !=
m_niChanges.end () && it->second.GetEvent () != event)
253 ni->emplace (event->GetEndTime (),
NiChange (0, event));
254 NS_ASSERT_MSG (noiseInterferenceW >= 0,
"CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
255 return noiseInterferenceW;
266 uint64_t nbits =
static_cast<uint64_t
> (rate * duration.
GetSeconds ());
269 nbits /= txVector.
GetNss ();
273 ", SNIR improvement=+" << 10 * std::log10 (gain) <<
"dB");
276 double csr =
m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
286 auto j = ni->begin ();
287 Time previous = j->first;
288 WifiMode payloadMode =
event->GetPayloadMode ();
294 Time windowStart = plcpPayloadStart +
window.first;
295 Time windowEnd = plcpPayloadStart +
window.second;
297 double powerW =
event->GetRxPowerW ();
298 while (++j != ni->end ())
300 Time current = j->first;
301 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
304 if (previous >= windowStart)
310 payloadMode, txVector);
311 NS_LOG_DEBUG (
"Both previous and current point to the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
314 else if (current >= windowStart)
319 current - windowStart,
320 payloadMode, txVector);
321 NS_LOG_DEBUG (
"previous is before windowed payload and current is in the windowed payload: mode=" << payloadMode <<
", psr=" << psr);
323 noiseInterferenceW = j->second.GetPower () - powerW;
325 if (previous > windowEnd)
327 NS_LOG_DEBUG (
"Stop: new previous=" << previous <<
" after time window end=" << windowEnd);
332 double per = 1 - psr;
342 auto j = ni->begin ();
343 Time previous = j->first;
351 double powerW =
event->GetRxPowerW ();
352 while (++j != ni->end ())
354 Time current = j->first;
355 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
358 if (previous >= plcpPayloadStart)
361 NS_LOG_DEBUG (
"Case 1 - previous and current after playload start: nothing to do");
364 else if (previous >= plcpTrainingSymbolsStart)
368 NS_LOG_DEBUG (
"Case 2 - previous is in training or in SIG-B: nothing to do");
371 else if (previous >= plcpHsigHeaderStart)
375 NS_LOG_DEBUG (
"Case 3cii - previous is in HT-SIG or SIG-A: nothing to do");
378 else if (previous >= plcpHeaderStart)
382 if (current >= plcpPayloadStart)
387 plcpHsigHeaderStart - previous,
388 headerMode, txVector);
389 NS_LOG_DEBUG (
"Case 4a - previous in L-SIG and current after payload start: mode=" << headerMode <<
", psr=" << psr);
392 else if (current >= plcpTrainingSymbolsStart)
398 plcpHsigHeaderStart - previous,
399 headerMode, txVector);
400 NS_LOG_DEBUG (
"Case 4a - previous in L-SIG and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
403 else if (current >= plcpHsigHeaderStart)
409 plcpHsigHeaderStart - previous,
410 headerMode, txVector);
411 NS_LOG_DEBUG (
"Case 4ci - previous is in L-SIG and current in HT-SIG or in SIG-A: mode=" << headerMode <<
", psr=" << psr);
420 headerMode, txVector);
421 NS_LOG_DEBUG (
"Case 4d - current with previous in L-SIG: mode=" << headerMode <<
", psr=" << psr);
428 if (current >= plcpPayloadStart)
433 plcpHsigHeaderStart - plcpHeaderStart,
434 headerMode, txVector);
435 NS_LOG_DEBUG (
"Case 5aii - previous is in the preamble and current is after payload start: mode=" << headerMode <<
", psr=" << psr);
438 else if (current >= plcpTrainingSymbolsStart)
444 plcpHsigHeaderStart - plcpHeaderStart,
445 headerMode, txVector);
446 NS_LOG_DEBUG (
"Case 5b - previous is in the preamble and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
449 else if (current >= plcpHsigHeaderStart)
455 plcpHsigHeaderStart - plcpHeaderStart,
456 headerMode, txVector);
457 NS_LOG_DEBUG (
"Case 5b - previous is in the preamble and current in HT-SIG or in SIG-A: mode=" << headerMode <<
", psr=" << psr);
460 else if (current >= plcpHeaderStart)
466 current - plcpHeaderStart,
467 headerMode, txVector);
468 NS_LOG_DEBUG (
"Case 5d - previous is in the preamble and current is in L-SIG: mode=" << headerMode <<
", psr=" << psr);
472 noiseInterferenceW = j->second.GetPower () - powerW;
476 double per = 1 - psr;
486 auto j = ni->begin ();
487 Time previous = j->first;
511 double powerW =
event->GetRxPowerW ();
512 while (++j != ni->end ())
514 Time current = j->first;
515 NS_LOG_DEBUG (
"previous= " << previous <<
", current=" << current);
518 if (previous >= plcpPayloadStart)
521 NS_LOG_DEBUG (
"Case 1 - previous and current after playload start: nothing to do");
524 else if (previous >= plcpTrainingSymbolsStart)
528 if (current >= plcpPayloadStart)
533 plcpPayloadStart - previous,
534 mcsHeaderMode, txVector);
535 NS_LOG_DEBUG (
"Case 2a - previous is in training or in SIG-B and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
544 mcsHeaderMode, txVector);
545 NS_LOG_DEBUG (
"Case 2b - previous is in training or in SIG-B and current is in training or in SIG-B: mode=" << mcsHeaderMode <<
", psr=" << psr);
549 else if (previous >= plcpHsigHeaderStart)
553 if (current >= plcpPayloadStart)
558 plcpPayloadStart - plcpTrainingSymbolsStart,
559 mcsHeaderMode, txVector);
567 plcpTrainingSymbolsStart - previous,
568 headerMode, txVector);
569 NS_LOG_DEBUG (
"Case 3ai - previous is in SIG-A and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
577 plcpTrainingSymbolsStart - previous,
578 mcsHeaderMode, txVector);
579 NS_LOG_DEBUG (
"Case 3aii - previous is in HT-SIG and current after payload start: mode=" << mcsHeaderMode <<
", psr=" << psr);
583 else if (current >= plcpTrainingSymbolsStart)
588 current - plcpTrainingSymbolsStart,
589 mcsHeaderMode, txVector);
597 plcpTrainingSymbolsStart - previous,
598 headerMode, txVector);
599 NS_LOG_DEBUG (
"Case 3bi - previous is in SIG-A and current is in training or in SIG-B: mode=" << headerMode <<
", psr=" << psr);
607 plcpTrainingSymbolsStart - previous,
608 mcsHeaderMode, txVector);
609 NS_LOG_DEBUG (
"Case 3bii - previous is in HT-SIG and current is in HT training: mode=" << mcsHeaderMode <<
", psr=" << psr);
623 headerMode, txVector);
624 NS_LOG_DEBUG (
"Case 3ci - previous with current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
633 mcsHeaderMode, txVector);
634 NS_LOG_DEBUG (
"Case 3cii - previous with current in HT-SIG: mode=" << mcsHeaderMode <<
", psr=" << psr);
639 else if (previous >= plcpHeaderStart)
643 if (current >= plcpPayloadStart)
649 NS_LOG_DEBUG (
"Case 4ai - previous in L-SIG and current after payload start: nothing to do");
657 plcpPayloadStart - plcpTrainingSymbolsStart,
658 mcsHeaderMode, txVector);
662 plcpTrainingSymbolsStart - plcpHsigHeaderStart,
663 headerMode, txVector);
664 NS_LOG_DEBUG (
"Case 4aii - previous is in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
672 plcpPayloadStart - plcpHsigHeaderStart,
673 mcsHeaderMode, txVector);
674 NS_LOG_DEBUG (
"Case 4aiii - previous in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
678 else if (current >= plcpTrainingSymbolsStart)
687 current - plcpTrainingSymbolsStart,
688 mcsHeaderMode, txVector);
692 plcpTrainingSymbolsStart - plcpHsigHeaderStart,
693 headerMode, txVector);
694 NS_LOG_DEBUG (
"Case 4bi - previous is in L-SIG and current in training or in SIG-B: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
702 current - plcpHsigHeaderStart,
703 mcsHeaderMode, txVector);
704 NS_LOG_DEBUG (
"Case 4bii - previous in L-SIG and current in HT training: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
708 else if (current >= plcpHsigHeaderStart)
717 current - plcpHsigHeaderStart,
718 headerMode, txVector);
719 NS_LOG_DEBUG (
"Case 4ci - previous is in L-SIG and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
727 current - plcpHsigHeaderStart,
728 mcsHeaderMode, txVector);
729 NS_LOG_DEBUG (
"Case 4cii - previous in L-SIG and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
736 NS_LOG_DEBUG (
"Case 4d - current with previous in L-SIG: nothing to do");
743 if (current >= plcpPayloadStart)
749 NS_LOG_DEBUG (
"Case 5ai - previous is in the preamble and current is after payload start: nothing to do");
757 plcpPayloadStart - plcpTrainingSymbolsStart,
758 mcsHeaderMode, txVector);
762 plcpTrainingSymbolsStart - plcpHsigHeaderStart,
763 headerMode, txVector);
764 NS_LOG_DEBUG (
"Case 5aii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
772 plcpPayloadStart - plcpHsigHeaderStart,
773 mcsHeaderMode, txVector);
774 NS_LOG_DEBUG (
"Case 5aiii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
778 else if (current >= plcpTrainingSymbolsStart)
787 current - plcpTrainingSymbolsStart,
788 mcsHeaderMode, txVector);
792 plcpTrainingSymbolsStart - plcpHsigHeaderStart,
793 headerMode, txVector);
794 NS_LOG_DEBUG (
"Case 5bi - previous is in the preamble and current in training or in SIG-B: mcs mode=" << mcsHeaderMode <<
", legacy mode=" << headerMode <<
", psr=" << psr);
802 current - plcpHsigHeaderStart,
803 mcsHeaderMode, txVector);
804 NS_LOG_DEBUG (
"Case 5bii - previous is in the preamble and current in HT training: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
808 else if (current >= plcpHsigHeaderStart)
817 current - plcpHsigHeaderStart,
818 headerMode, txVector);
819 NS_LOG_DEBUG (
"Case 5ci - previous is in preamble and current in SIG-A: mode=" << headerMode <<
", psr=" << psr);
827 current - plcpHsigHeaderStart,
828 mcsHeaderMode, txVector);
829 NS_LOG_DEBUG (
"Case 5cii - previous in preamble and current in HT-SIG: mcs mode=" << mcsHeaderMode <<
", psr=" << psr);
833 else if (current >= plcpHeaderStart)
837 NS_LOG_DEBUG (
"Case 5d - previous is in the preamble and current is in L-SIG: nothing to do");
841 noiseInterferenceW = j->second.GetPower () - powerW;
845 double per = 1 - psr;
850 InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, std::pair<Time, Time> relativeMpduStartStop) const
856 event->GetTxVector ().GetChannelWidth ());
876 event->GetTxVector ().GetChannelWidth ());
887 event->GetTxVector ().GetChannelWidth ());
907 event->GetTxVector ().GetChannelWidth ());
930 InterferenceHelper::NiChanges::const_iterator
936 InterferenceHelper::NiChanges::const_iterator
946 InterferenceHelper::NiChanges::iterator
double GetRxPowerW(void) const
Return the receive power (w).
void AddPower(double power)
Add a given amount of power.
Simulation virtual time values and global simulation resolution.
void AddForeignSignal(Time duration, double rxPower)
Add a non-Wifi signal to interference helper.
Signal event for a packet.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
NiChanges::iterator AddNiChangeEvent(Time moment, NiChange change)
Add NiChange to the list at the appropriate position and return the iterator of the new event...
Control the scheduling of simulation events.
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
double m_rxPowerW
receive power in watts
Ptr< ErrorRateModel > GetErrorRateModel(void) const
Return the error rate model.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
double CalculateLegacyPhyHeaderPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the legacy PHY header.
Time GetEndTime(void) const
Return the end time of the signal.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
handles interference calculations
static Time GetPlcpHtSigHeaderDuration(WifiPreamble preamble)
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
Time GetStartTime(void) const
Return the start time of the signal.
Ptr< Event > GetEvent(void) const
Return the event causes the corresponding NI change.
Ptr< ErrorRateModel > m_errorRateModel
error rate model
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
static Time GetPlcpSigA1Duration(WifiPreamble preamble)
Event(Ptr< const Packet > packet, WifiTxVector txVector, Time duration, double rxPower)
Create an Event with the given parameters.
WifiMode GetPayloadMode(void) const
Return the Wi-Fi mode used for the payload.
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode, WifiTxVector txVector) const
Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode. ...
WifiPreamble GetPreambleType(void) const
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
static Time GetPlcpSigA2Duration(WifiPreamble preamble)
static Time GetPlcpPreambleDuration(WifiTxVector txVector)
Time GetEnergyDuration(double energyW) const
Ptr< Event > Add(Ptr< const Packet > packet, WifiTxVector txVector, Time duration, double rxPower)
Add the packet-related signal to interference helper.
static Time GetPlcpSigBDuration(WifiPreamble preamble)
NiChanges m_niChanges
Experimental: needed for energy duration calculation.
WifiMode GetMode(void) const
Ptr< const Packet > GetPacket(void) const
Return the packet.
uint8_t GetNTx(void) const
WifiModulationClass GetModulationClass() const
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChanges *ni) const
Calculate noise and interference power in W.
WifiTxVector GetTxVector(void) const
Return the TXVECTOR of the packet.
double CalculateNonLegacyPhyHeaderPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the non-legacy PHY header.
double m_noiseFigure
noise figure (linear)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void NotifyRxStart()
Notify that RX has started.
Noise and Interference (thus Ni) event.
void EraseEvents(void)
Erase all events.
double CalculateSnr(Ptr< Event > event) const
Calculate the SNIR for the event (starting from now until the event end).
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
static Time Now(void)
Return the current simulation virtual time.
double RatioToDb(double ratio)
Convert from ratio to dB.
void NotifyRxEnd()
Notify that RX has ended.
void SetNoiseFigure(double value)
Set the noise figure.
double m_firstPower
first power
NiChange(double power, Ptr< Event > event)
Create a NiChange at the given time and the amount of NI change.
double CalculatePayloadPer(Ptr< const Event > event, NiChanges *ni, std::pair< Time, Time > window) const
Calculate the error rate of the given PLCP payload only in the provided time window (thus enabling pe...
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
static WifiMode GetVhtPlcpHeaderMode()
WifiTxVector m_txVector
TXVECTOR.
static WifiMode GetHePlcpHeaderMode()
void AppendEvent(Ptr< Event > event)
Append the given Event.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
NiChanges::const_iterator GetNextPosition(Time moment) const
Returns an iterator to the first nichange that is later than moment.
double GetPower(void) const
Return the power.
uint16_t GetChannelWidth(void) const
Ptr< const Packet > m_packet
packet
static WifiMode GetPlcpHeaderMode(WifiTxVector txVector)
static Time GetPlcpTrainingSymbolDuration(WifiTxVector txVector)
static Time GetPlcpHeaderDuration(WifiTxVector txVector)
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
static WifiMode GetHtPlcpHeaderMode()
NiChanges::const_iterator GetPreviousPosition(Time moment) const
Returns an iterator to the first nichange that is later than moment.
uint8_t GetNss(void) const
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChanges
bool m_rxing
flag whether it is in receiving state
Time m_startTime
start time