diff -r 6fc881b42bff src/devices/wifi/interference-helper.cc --- a/src/devices/wifi/interference-helper.cc Wed Jan 27 12:09:07 2010 +0100 +++ b/src/devices/wifi/interference-helper.cc Thu Jan 28 15:32:40 2010 +0300 @@ -60,19 +60,6 @@ { return m_endTime; } -bool -InterferenceHelper::Event::Overlaps (Time time) const -{ - if (m_startTime <= time && - m_endTime >= time) - { - return true; - } - else - { - return false; - } -} double InterferenceHelper::Event::GetRxPowerW (void) const { @@ -123,8 +110,9 @@ ****************************************************************/ InterferenceHelper::InterferenceHelper () - : m_maxPacketDuration (Seconds(0)), - m_errorRateModel (0) + : m_errorRateModel (0), + m_firstPower (0.0), + m_rxing (false) {} InterferenceHelper::~InterferenceHelper () { @@ -145,17 +133,10 @@ preamble, duration, rxPowerW); - - m_maxPacketDuration = std::max(duration, m_maxPacketDuration); AppendEvent (event); return event; } -Time -InterferenceHelper::GetMaxPacketDuration (void) const -{ - return m_maxPacketDuration; -} void InterferenceHelper::SetNoiseFigure (double value) @@ -185,45 +166,23 @@ InterferenceHelper::GetEnergyDuration (double energyW) { Time now = Simulator::Now (); - - // first, we iterate over all events and, each event - // which contributes energy to the channel now is - // appended to the noise interference array. - Events::const_iterator i = m_events.begin (); double noiseInterferenceW = 0.0; - NiChanges ni; - while (i != m_events.end ()) - { - Ptr ev = *i; - NS_ASSERT (ev->GetStartTime () <= now); - if (ev->GetEndTime () > now) - { - ni.push_back (NiChange (ev->GetEndTime (), -ev->GetRxPowerW ())); - noiseInterferenceW += ev->GetRxPowerW (); - } - i++; - } - if (noiseInterferenceW < energyW) - { - return MicroSeconds (0); - } - - /* quicksort vector of NI changes by time. - */ - std::sort (ni.begin (), ni.end (), std::less ()); - - // Now, we iterate the piecewise linear noise function Time end = now; - for (NiChanges::const_iterator i = ni.begin (); i != ni.end (); i++) + noiseInterferenceW = m_firstPower; + for (NiChanges::const_iterator i = m_niChanges.begin (); i != m_niChanges.end (); i++) { noiseInterferenceW += i->GetDelta (); end = i->GetTime (); - if (noiseInterferenceW < energyW) - { - break; - } + if (end < now) + { + continue; + } + if (noiseInterferenceW < energyW) + { + break; + } } - return end - now; + return end > now ? end - now : MicroSeconds (0); } WifiMode @@ -414,24 +373,23 @@ void InterferenceHelper::AppendEvent (Ptr event) { - /* attempt to remove the events which are - * not useful anymore. - * i.e.: all events which end _before_ - * now - m_maxPacketDuration - */ - - if (Simulator::Now () > GetMaxPacketDuration ()) + Time now = Simulator::Now (); + if (!m_rxing) { - Time end = Simulator::Now () - GetMaxPacketDuration (); - Events::iterator i = m_events.begin (); - while (i != m_events.end () && - (*i)->GetEndTime () <= end) + NiChanges::iterator nowIterator = GetPosition (now); + for (NiChanges::iterator i = m_niChanges.begin (); i != nowIterator; i++) { - i++; + m_firstPower += i->GetDelta (); } - EraseEvents (m_events.begin (), i); - } - m_events.push_back (event); + m_niChanges.erase (m_niChanges.begin (), nowIterator); + m_niChanges.insert (m_niChanges.begin (), NiChange (event->GetStartTime (), event->GetRxPowerW ())); + } + else + { + AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW ())); + } + AddNiChangeEvent(NiChange (event->GetEndTime (), -event->GetRxPowerW ())); + } @@ -452,35 +410,18 @@ double InterferenceHelper::CalculateNoiseInterferenceW (Ptr event, NiChanges *ni) const { - Events::const_iterator i = m_events.begin (); - double noiseInterference = 0.0; - while (i != m_events.end ()) + double noiseInterference = m_firstPower; + NS_ASSERT (m_rxing); + for (NiChanges::const_iterator i = m_niChanges.begin () + 1; i != m_niChanges.end (); i++) { - if (event == (*i)) + if ((event->GetEndTime () == i->GetTime ()) && event->GetRxPowerW () == -i->GetDelta ()) { - i++; - continue; + break; } - if ((*i)->Overlaps (event->GetStartTime ())) - { - noiseInterference += (*i)->GetRxPowerW (); - } - else if (event->Overlaps ((*i)->GetStartTime ())) - { - ni->push_back (NiChange ((*i)->GetStartTime (), (*i)->GetRxPowerW ())); - } - if (event->Overlaps ((*i)->GetEndTime ())) - { - ni->push_back (NiChange ((*i)->GetEndTime (), -(*i)->GetRxPowerW ())); - } - i++; + ni->push_back (*i); } - ni->push_back (NiChange (event->GetStartTime (), noiseInterference)); + ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference)); ni->push_back (NiChange (event->GetEndTime (), 0)); - - /* quicksort vector of NI changes by time. */ - std::sort (ni->begin (), ni->end (), std::less ()); - return noiseInterference; } @@ -607,21 +548,28 @@ void InterferenceHelper::EraseEvents (void) { - for (Events::iterator i = m_events.begin (); i != m_events.end (); ++i) - { - *i = 0; - } - m_events.clear (); + m_niChanges.clear (); + m_firstPower = 0.0; } +InterferenceHelper::NiChanges::iterator +InterferenceHelper::GetPosition (Time moment) +{ + return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0)); +} void -InterferenceHelper::EraseEvents (Events::iterator start, Events::iterator end) -{ - for (Events::iterator i = start; i != end; ++i) - { - *i = 0; - } - m_events.erase (start, end); +InterferenceHelper::AddNiChangeEvent (NiChange change) +{ + m_niChanges.insert (GetPosition (change.GetTime ()), change); } - +void +InterferenceHelper::NotifyRxStart () +{ + m_rxing = true; +} +void +InterferenceHelper::NotifyRxEnd () +{ + m_rxing = false; +} } // namespace ns3 diff -r 6fc881b42bff src/devices/wifi/interference-helper.h --- a/src/devices/wifi/interference-helper.h Wed Jan 27 12:09:07 2010 +0100 +++ b/src/devices/wifi/interference-helper.h Thu Jan 28 15:32:40 2010 +0300 @@ -47,7 +47,6 @@ Time GetDuration (void) const; Time GetStartTime (void) const; Time GetEndTime (void) const; - bool Overlaps (Time time) const; double GetRxPowerW (void) const; uint32_t GetSize (void) const; WifiMode GetPayloadMode (void) const; @@ -95,6 +94,8 @@ Time duration, double rxPower); struct InterferenceHelper::SnrPer CalculateSnrPer (Ptr event); + void NotifyRxStart (); + void NotifyRxEnd (); void EraseEvents (void); private: class NiChange { @@ -110,8 +111,6 @@ typedef std::vector NiChanges; typedef std::list > Events; - void EraseEvents (Events::iterator start, Events::iterator end); - InterferenceHelper (const InterferenceHelper &o); InterferenceHelper &operator = (const InterferenceHelper &o); void AppendEvent (Ptr event); @@ -119,12 +118,16 @@ double CalculateSnr (double signal, double noiseInterference, WifiMode mode) const; double CalculateChunkSuccessRate (double snir, Time delay, WifiMode mode) const; double CalculatePer (Ptr event, NiChanges *ni) const; - Time GetMaxPacketDuration (void) const; - Time m_maxPacketDuration; double m_noiseFigure; /**< noise figure (linear) */ - Events m_events; Ptr m_errorRateModel; + ///Experimental: needed for energy duration calculation + NiChanges m_niChanges; + double m_firstPower; + bool m_rxing; + /// Returns an iterator to the first nichange, which is later than moment + NiChanges::iterator GetPosition (Time moment); + void AddNiChangeEvent (NiChange change); }; } // namespace ns3 diff -r 6fc881b42bff src/devices/wifi/yans-wifi-phy.cc --- a/src/devices/wifi/yans-wifi-phy.cc Wed Jan 27 12:09:07 2010 +0100 +++ b/src/devices/wifi/yans-wifi-phy.cc Thu Jan 28 15:32:40 2010 +0300 @@ -459,6 +459,7 @@ m_state->SwitchToRx (rxDuration); NS_ASSERT (m_endRxEvent.IsExpired ()); NotifyRxBegin (packet); + m_interference.NotifyRxStart(); m_endRxEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndReceive, this, packet, event); @@ -504,6 +505,7 @@ if (m_state->IsStateRx ()) { m_endRxEvent.Cancel (); + m_interference.NotifyRxEnd (); } NotifyTxBegin (packet); uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000; @@ -739,6 +741,7 @@ struct InterferenceHelper::SnrPer snrPer; snrPer = m_interference.CalculateSnrPer (event); + m_interference.NotifyRxEnd(); NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<< ", snr="<