diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 8b35f5edd..a8bf6e9ca 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -43,6 +43,7 @@ Bugs fixed - Bug 2764 - wifi: WifiSpectrumModelId doesn't distinguish 11ax from legacy - Bug 2766 - core: Modify logging for int64x64 to avoid stack overflow - Bug 2768 - lte: LteUeNetDevice has a null MAC address +- Bug 2791 - wifi: Interference Helper gives negative trace value for Interference Power - Bug 2807 - energy: GetTotalEnergyConsumption is not updated correctly - Bug 2809 - wifi: Wifi doesn't fully stop when energy is depleted - Bug 2813 - wifi: OFDM 10 MHz and 5 MHz PHYs do not have correct subcarrier frequency spacings diff --git a/src/wifi/model/interference-helper.cc b/src/wifi/model/interference-helper.cc index 989e7bf6d..0660e8b4a 100644 --- a/src/wifi/model/interference-helper.cc +++ b/src/wifi/model/interference-helper.cc @@ -88,23 +88,22 @@ InterferenceHelper::Event::GetPayloadMode (void) const * short period of time. ****************************************************************/ -InterferenceHelper::NiChange::NiChange (Time time, double delta, Ptr event) - : m_time (time), - m_delta (delta), +InterferenceHelper::NiChange::NiChange (double power, Ptr event) + : m_power (power), m_event (event) { } -Time -InterferenceHelper::NiChange::GetTime (void) const +double +InterferenceHelper::NiChange::GetPower (void) const { - return m_time; + return m_power; } -double -InterferenceHelper::NiChange::GetDelta (void) const +void +InterferenceHelper::NiChange::AddPower (double power) { - return m_delta; + m_power += power; } Ptr @@ -113,12 +112,6 @@ InterferenceHelper::NiChange::GetEvent (void) const return m_event; } -bool -InterferenceHelper::NiChange::operator < (const InterferenceHelper::NiChange& o) const -{ - return (m_time < o.m_time); -} - /**************************************************************** * The actual InterferenceHelper @@ -130,6 +123,8 @@ InterferenceHelper::InterferenceHelper () 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 () @@ -141,8 +136,7 @@ InterferenceHelper::~InterferenceHelper () Ptr InterferenceHelper::Add (Ptr packet, WifiTxVector txVector, Time duration, double rxPowerW) { - Ptr event; - event = Create (packet, txVector, duration, rxPowerW); + Ptr event = Create (packet, txVector, duration, rxPowerW); AppendEvent (event); return event; } @@ -191,17 +185,12 @@ Time InterferenceHelper::GetEnergyDuration (double energyW) const { Time now = Simulator::Now (); - double noiseInterferenceW = 0; - Time end = now; - noiseInterferenceW = m_firstPower; - for (NiChanges::const_iterator i = m_niChanges.begin (); i != m_niChanges.end (); i++) + auto i = GetPreviousPosition (now); + Time end = i->first; + for (; i != m_niChanges.end (); ++i) { - noiseInterferenceW += i->GetDelta (); - end = i->GetTime (); - if (end < now) - { - continue; - } + double noiseInterferenceW = i->second.GetPower (); + end = i->first; if (noiseInterferenceW < energyW) { break; @@ -213,18 +202,25 @@ InterferenceHelper::GetEnergyDuration (double energyW) const void InterferenceHelper::AppendEvent (Ptr event) { - Time now = Simulator::Now (); + 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) { - NiChanges::const_iterator nowIterator = GetPosition (now); - for (NiChanges::const_iterator i = m_niChanges.begin (); i != nowIterator; i++) - { - m_firstPower += i->GetDelta (); - } - m_niChanges.erase (m_niChanges.begin (), nowIterator); + 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 ()); } - AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW (), event)); - AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW (), event)); } double @@ -246,41 +242,19 @@ double InterferenceHelper::CalculateNoiseInterferenceW (Ptr event, NiChanges *ni) const { double noiseInterference = m_firstPower; - NiChanges::const_iterator eventIterator = m_niChanges.begin (); - while (eventIterator != m_niChanges.end ()) + auto it = m_niChanges.find (event->GetStartTime ()); + for (; it != m_niChanges.end () && it->second.GetEvent () != event; ++it) { - // Iterate the NI change list from the beginning to the end - // until find the position of the event in the NI change list - // The reason of using the event that causes the NI change to identify - // different NI changes is because in some special cases - // different NI changes happen at the same time with the same delta - // value. Therefore, it may be impossible to identify a NI change that belongs - // to which event based on just the NI time and NI delta value - if (eventIterator->GetEvent () != event) - { - // The NI changes which happen before the event should be considered - // as the interference. This considers the case that the receiving event - // arrives while another receiving event is going on. The SINR of - // the newly arrived event is calculated for checking the possibility of frame capture - noiseInterference += eventIterator->GetDelta (); - } - else - { - break; - } - ++eventIterator; + noiseInterference = it->second.GetPower (); } - - for (NiChanges::const_iterator i = eventIterator + 1; i != m_niChanges.end (); ++i) + ni->emplace (event->GetStartTime (), NiChange (0, event)); + while (++it != m_niChanges.end () && it->second.GetEvent () != event) { - if (event->GetEndTime () == i->GetTime () && event == i->GetEvent ()) - { - break; - } - ni->push_back (*i); + ni->insert (*it); } - ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference, event)); - ni->push_back (NiChange (event->GetEndTime (), 0, event)); + ni->emplace (event->GetEndTime (), NiChange (0, event)); + NS_ABORT_MSG_IF (noiseInterference < 0, "noiseInterference < 0: " << + noiseInterference); return noiseInterference; } @@ -312,20 +286,19 @@ InterferenceHelper::CalculatePlcpPayloadPer (PtrGetTxVector (); double psr = 1.0; /* Packet Success Rate */ - NiChanges::const_iterator j = ni->begin (); - Time previous = (*j).GetTime (); + auto j = ni->begin (); + Time previous = j->first; WifiMode payloadMode = event->GetPayloadMode (); WifiPreamble preamble = txVector.GetPreambleType (); - Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (txVector); //packet start time + preamble + Time plcpHeaderStart = j->first + WifiPhy::GetPlcpPreambleDuration (txVector); //packet start time + preamble Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (txVector); //packet start time + preamble + L-SIG Time plcpTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpSigA1Duration (preamble) + WifiPhy::GetPlcpSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A Time plcpPayloadStart = plcpTrainingSymbolsStart + WifiPhy::GetPlcpTrainingSymbolDuration (txVector) + WifiPhy::GetPlcpSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B - double noiseInterferenceW = (*j).GetDelta (); + double noiseInterferenceW = m_firstPower; double powerW = event->GetRxPowerW (); - j++; - while (ni->end () != j) + while (++j != ni->end ()) { - Time current = (*j).GetTime (); + Time current = j->first; NS_LOG_DEBUG ("previous= " << previous << ", current=" << current); NS_ASSERT (current >= previous); //Case 1: Both previous and current point to the payload @@ -348,9 +321,8 @@ InterferenceHelper::CalculatePlcpPayloadPer (Ptr namespace ns3 { @@ -177,7 +178,7 @@ private: * * \return struct of SNR and PER */ - struct InterferenceHelper::SnrPer CalculatePlcpPayloadSnrPer (Ptr event); + struct InterferenceHelper::SnrPer CalculatePlcpPayloadSnrPer (Ptr event) const; /** * Calculate the SNIR at the start of the plcp header and accumulate * all SNIR changes in the snir vector. @@ -186,7 +187,7 @@ private: * * \return struct of SNR and PER */ - struct InterferenceHelper::SnrPer CalculatePlcpHeaderSnrPer (Ptr event); + struct InterferenceHelper::SnrPer CalculatePlcpHeaderSnrPer (Ptr event) const; /** * Notify that RX has started. @@ -212,47 +213,39 @@ public: /** * Create a NiChange at the given time and the amount of NI change. * - * \param time time of the event - * \param delta the power + * \param power the power * \param event causes this NI change */ - NiChange (Time time, double delta, Ptr event); - /** - * Return the event time. - * - * \return the event time. - */ - Time GetTime (void) const; + NiChange (double power, Ptr event); /** * Return the power * * \return the power */ - double GetDelta (void) const; + double GetPower (void) const; + /** + * Add a given amount of power. + * + * \param power the power to be added to the existing value + */ + void AddPower (double power); /** * Return the event causes the corresponding NI change * * \return the event */ Ptr GetEvent (void) const; - /** - * Compare the event time of two NiChange objects (a < o). - * - * \param o - * \return true if a < o.time, false otherwise - */ - bool operator < (const NiChange& o) const; private: - Time m_time; ///< time - double m_delta; ///< delta + double m_power; ///< power Ptr m_event; ///< event }; + /** - * typedef for a vector of NiChanges + * typedef for a multimap of NiChanges */ - typedef std::vector NiChanges; + typedef std::multimap NiChanges; /** * Append the given Event. @@ -322,18 +315,36 @@ private: bool m_rxing; ///< flag whether it is in receiving state /** - * Returns a const iterator to the first nichange, which is later than moment + * 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::const_iterator GetPosition (Time moment); + NiChanges::const_iterator GetNextPosition (Time moment) const; /** - * Add NiChange to the list at the appropriate position. + * Returns an iterator to the first nichange that is later than moment * - * \param change + * \param moment time to check from + * \returns an iterator to the list of NiChanges */ - void AddNiChangeEvent (NiChange change); + //NiChanges::iterator GetNextPosition (Time moment); + /** + * Returns an iterator to the last nichange that is before than moment + * + * \param moment time to check from + * \returns an iterator to the list of NiChanges + */ + NiChanges::const_iterator GetPreviousPosition (Time moment) const; + + /** + * Add NiChange to the list at the appropriate position and + * return the iterator of the new event. + * + * \param moment + * \param change + * \returns the iterator of the new event + */ + NiChanges::iterator AddNiChangeEvent (Time moment, NiChange change); }; } //namespace ns3