--- a/src/devices/wifi/interference-helper.cc Mon Aug 02 13:15:36 2010 +0200
+++ b/src/devices/wifi/interference-helper.cc Mon Aug 02 17:09:16 2010 +0200
@@ -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<Event> 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<NiChange> ());
-
- // 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
@@ -412,24 +371,23 @@
void
InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> 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 ()));
+
}
@@ -450,35 +408,18 @@
double
InterferenceHelper::CalculateNoiseInterferenceW (Ptr<InterferenceHelper::Event> 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))
- {
- i++;
- continue;
- }
- if ((*i)->Overlaps (event->GetStartTime ()))
- {
- noiseInterference += (*i)->GetRxPowerW ();
- }
- else if (event->Overlaps ((*i)->GetStartTime ()))
+ if ((event->GetEndTime () == i->GetTime ()) && event->GetRxPowerW () == -i->GetDelta ())
{
- ni->push_back (NiChange ((*i)->GetStartTime (), (*i)->GetRxPowerW ()));
- }
- if (event->Overlaps ((*i)->GetEndTime ()))
- {
- ni->push_back (NiChange ((*i)->GetEndTime (), -(*i)->GetRxPowerW ()));
+ break;
}
- 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<NiChange> ());
-
return noiseInterference;
}
@@ -605,21 +546,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
--- a/src/devices/wifi/interference-helper.h Mon Aug 02 13:15:36 2010 +0200
+++ b/src/devices/wifi/interference-helper.h Mon Aug 02 17:09:16 2010 +0200
@@ -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<InterferenceHelper::Event> event);
+ void NotifyRxStart ();
+ void NotifyRxEnd ();
void EraseEvents (void);
private:
class NiChange {
@@ -110,8 +111,6 @@
typedef std::vector <NiChange> NiChanges;
typedef std::list<Ptr<Event> > Events;
- void EraseEvents (Events::iterator start, Events::iterator end);
-
InterferenceHelper (const InterferenceHelper &o);
InterferenceHelper &operator = (const InterferenceHelper &o);
void AppendEvent (Ptr<Event> 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<const Event> event, NiChanges *ni) const;
- Time GetMaxPacketDuration (void) const;
- Time m_maxPacketDuration;
double m_noiseFigure; /**< noise figure (linear) */
- Events m_events;
Ptr<ErrorRateModel> 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
--- a/src/devices/wifi/yans-wifi-phy.cc Mon Aug 02 13:15:36 2010 +0200
+++ b/src/devices/wifi/yans-wifi-phy.cc Mon Aug 02 17:09:16 2010 +0200
@@ -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;
@@ -754,6 +756,7 @@
struct InterferenceHelper::SnrPer snrPer;
snrPer = m_interference.CalculateSnrPer (event);
+ m_interference.NotifyRxEnd();
NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
", snr="<<snrPer.snr<<", per="<<snrPer.per<<", size="<<packet->GetSize ());