First version with interference handling.
authorSascha Jopen <jopen@cs.uni-bonn.de>
Thu, 27 Mar 2014 16:56:15 +0100
changeset 10728 62d4098c1c22
parent 10727 18930b0efc01
child 10729 585982c4b380
First version with interference handling.
src/lr-wpan/model/lr-wpan-interference-helper.cc
src/lr-wpan/model/lr-wpan-interference-helper.h
src/lr-wpan/model/lr-wpan-phy.cc
src/lr-wpan/model/lr-wpan-phy.h
src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc
src/lr-wpan/model/lr-wpan-spectrum-value-helper.h
src/lr-wpan/test/lr-wpan-error-model-test.cc
src/lr-wpan/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lr-wpan/model/lr-wpan-interference-helper.cc	Thu Mar 27 16:56:15 2014 +0100
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 Fraunhofer FKIE
+ *
+ * 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:
+ *  Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
+ */
+#include "lr-wpan-interference-helper.h"
+#include <ns3/spectrum-value.h>
+#include <ns3/spectrum-model.h>
+
+namespace ns3 {
+
+LrWpanInterferenceHelper::LrWpanInterferenceHelper (Ptr<const SpectrumModel> spectrumModel) :
+    m_spectrumModel (spectrumModel), m_dirty(true)
+{
+}
+
+LrWpanInterferenceHelper::~LrWpanInterferenceHelper ()
+{
+  m_spectrumModel = 0;
+  m_signal = 0;
+  m_signals.clear ();
+}
+
+bool
+LrWpanInterferenceHelper::AddSignal (Ptr<const SpectrumValue> signal)
+{
+  bool result = false;
+
+  if (signal->GetSpectrumModel () == m_spectrumModel)
+    {
+      result = m_signals.insert (signal).second;
+      if (result && !m_dirty)
+        {
+          *m_signal += *signal;
+        }
+    }
+  return result;
+}
+
+bool
+LrWpanInterferenceHelper::RemoveSignal (Ptr<const SpectrumValue> signal)
+{
+  bool result = false;
+
+  if (signal->GetSpectrumModel () == m_spectrumModel)
+    {
+      result = (m_signals.erase (signal) == 1);
+      if (result)
+        {
+          m_dirty = true;
+        }
+    }
+  return result;
+}
+
+void
+LrWpanInterferenceHelper::ClearSignals ()
+{
+  m_signals.clear ();
+  m_dirty = true;
+}
+
+Ptr<SpectrumValue>
+LrWpanInterferenceHelper::GetSignalPsd () const
+{
+  if (m_dirty)
+    {
+      // Sum up the current interference PSD.
+      std::set<Ptr<const SpectrumValue> >::const_iterator it;
+      m_signal = Create<SpectrumValue> (m_spectrumModel);
+      for (it = m_signals.begin (); it != m_signals.end (); ++it)
+        {
+          *m_signal += *(*it);
+        }
+      m_dirty = false;
+    }
+
+  return m_signal->Copy ();
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lr-wpan/model/lr-wpan-interference-helper.h	Thu Mar 27 16:56:15 2014 +0100
@@ -0,0 +1,53 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 Fraunhofer FKIE
+ *
+ * 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:
+ *  Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
+ */
+#ifndef LR_WPAN_LR_WPAN_INTERFERENCE_HELPER_H
+#define LR_WPAN_LR_WPAN_INTERFERENCE_HELPER_H
+
+#include <ns3/simple-ref-count.h>
+#include <ns3/ptr.h>
+#include <set>
+
+namespace ns3 {
+
+class SpectrumValue;
+class SpectrumModel;
+
+class LrWpanInterferenceHelper : public SimpleRefCount<LrWpanInterferenceHelper>
+{
+public:
+  LrWpanInterferenceHelper (Ptr<const SpectrumModel> spectrumModel);
+  ~LrWpanInterferenceHelper ();
+
+  bool AddSignal (Ptr<const SpectrumValue> signal);
+  bool RemoveSignal (Ptr<const SpectrumValue> signal);
+  void ClearSignals ();
+  Ptr<SpectrumValue> GetSignalPsd () const;
+  Ptr<const SpectrumModel> GetSpectrumModel () const;
+private:
+  Ptr<const SpectrumModel> m_spectrumModel;
+  std::set<Ptr<const SpectrumValue> > m_signals;
+  mutable Ptr<SpectrumValue> m_signal;
+  mutable bool m_dirty;
+};
+
+}
+
+#endif /* LR_WPAN_LR_WPAN_INTERFERENCE_HELPER_H */
--- a/src/lr-wpan/model/lr-wpan-phy.cc	Tue Mar 25 23:21:02 2014 +0100
+++ b/src/lr-wpan/model/lr-wpan-phy.cc	Thu Mar 27 16:56:15 2014 +0100
@@ -126,10 +126,12 @@
   m_txPsd = psdHelper.CreateTxPowerSpectralDensity (m_phyPIBAttributes.phyTransmitPower,
                                                     m_phyPIBAttributes.phyCurrentChannel);
   m_noise = psdHelper.CreateNoisePowerSpectralDensity (m_phyPIBAttributes.phyCurrentChannel);
-  m_rxPsd = 0;
-  Ptr <Packet> none = 0;
-  m_currentRxPacket = std::make_pair (none, true);
-  m_currentTxPacket = std::make_pair (none, true);
+  m_signal = Create<LrWpanInterferenceHelper> (m_noise->GetSpectrumModel ());
+  m_rxLastUpdate = Seconds (0);
+  Ptr<Packet> none_packet = 0;
+  Ptr<LrWpanSpectrumSignalParameters> none_params = 0;
+  m_currentRxPacket = std::make_pair (none_params, true);
+  m_currentTxPacket = std::make_pair (none_packet, true);
   m_errorModel = 0;
 
   ChangeTrxState (IEEE_802_15_4_PHY_TRX_OFF);
@@ -153,8 +155,8 @@
   m_device = 0;
   m_channel = 0;
   m_txPsd = 0;
-  m_rxPsd = 0;
   m_noise = 0;
+  m_signal = 0;
   m_errorModel = 0;
   m_pdDataIndicationCallback = MakeNullCallback< void, uint32_t, Ptr<Packet>, uint8_t > ();
   m_pdDataConfirmCallback = MakeNullCallback< void, LrWpanPhyEnumeration > ();
@@ -243,8 +245,6 @@
   m_antenna = a;
 }
 
-
-
 void
 LrWpanPhy::StartRx (Ptr<SpectrumSignalParameters> spectrumRxParams)
 {
@@ -253,118 +253,147 @@
 
 
   Ptr<LrWpanSpectrumSignalParameters> lrWpanRxParams = DynamicCast<LrWpanSpectrumSignalParameters> (spectrumRxParams);
+  NS_ASSERT (lrWpanRxParams != 0);
+  Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
+  NS_ASSERT (p != 0);
+
+  // Add any incoming packet to the current interference.
+  m_signal->AddSignal (lrWpanRxParams->psd);
 
   // Prevent PHY from receiving another packet while switching the transceiver state.
   if (m_trxState == IEEE_802_15_4_PHY_RX_ON && !m_setTRXState.IsRunning ())
     {
-      if (lrWpanRxParams != 0)
-        {
-          // The specification doesn't seem to refer to BUSY_RX, but vendor
-          // data sheets suggest that this is a substate of the RX_ON state
-          // that is entered after preamble detection when the digital receiver
-          // is enabled.  Here, for now, we use BUSY_RX to mark the period between
-          // StartRx() and EndRx() states.
-          Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
-          NS_ASSERT(p != 0);
-          m_rxPsd = lrWpanRxParams->psd;
-          m_rxTotalPower = psdHelper.TotalAvgPower (m_rxPsd);
+      // The specification doesn't seem to refer to BUSY_RX, but vendor
+      // data sheets suggest that this is a substate of the RX_ON state
+      // that is entered after preamble detection when the digital receiver
+      // is enabled.  Here, for now, we use BUSY_RX to mark the period between
+      // StartRx() and EndRx() states.
+
+      // We are going to BUSY_RX state when receiving the first bit of an SHR,
+      // as opposed to real receivers, which should go to this state only after
+      // successfully receiving the SHR.
 
-          if (m_rxTotalPower >= m_rxSensitivity)
-            {
-              ChangeTrxState (IEEE_802_15_4_PHY_BUSY_RX);
-              Time duration = lrWpanRxParams->duration;
-              m_currentRxPacket = std::make_pair (p, false);
+      // TODO: Check that the SINR is high enough for synchronizing to the packet.
+      // If synchronizing to the packet is possible, change to BUSY_RX state,
+      // otherwise drop the packet and stay in RX state. The actual synchronization
+      // is not modeled.
+      Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd ();
+      *interferenceAndNoise -= *lrWpanRxParams->psd;
+      *interferenceAndNoise += *m_noise;
+      double sinr = LrWpanSpectrumValueHelper::TotalAvgPower (lrWpanRxParams->psd) / LrWpanSpectrumValueHelper::TotalAvgPower (interferenceAndNoise);
+      if (sinr > 1)
+        {
+          ChangeTrxState (IEEE_802_15_4_PHY_BUSY_RX);
+          m_currentRxPacket = std::make_pair (lrWpanRxParams, false);
+          m_phyRxBeginTrace (p);
 
-              Simulator::Schedule (duration, &LrWpanPhy::EndRx, this);
-              m_phyRxBeginTrace (p);
-            }
-          else
-            {
-              // We are below our receiver sensitivity, the packet cannot be received.
-              // TODO: Add the power somehow to the interference.
-              m_phyRxDropTrace (p);
-            }
+          m_rxLastUpdate = Simulator::Now ();
         }
-      NS_LOG_LOGIC (this << " state: " << m_trxState << " m_rxTotalPower: " << m_rxTotalPower);
+      else
+        {
+          m_phyRxDropTrace (p);
+        }
     }
   else if (m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
     {
-      // TODO: Drop the second packet and add the signal power to the interference of
-      //       the currently received packet. Consider the received signal power
-      //       during CCA/ED, too.
+      // Drop the new packet.
       NS_LOG_DEBUG (this << " packet collision");
-      Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
       m_phyRxDropTrace (p);
     }
   else
     {
+      // Simply drop the packet.
       NS_LOG_DEBUG (this << " transceiver not in RX state");
-      Ptr<Packet> p = (lrWpanRxParams->packetBurst->GetPackets ()).front ();
       m_phyRxDropTrace (p);
     }
+
+  // Always call EndRx to update the interference.
+  // TODO: Do we need to keep track of these events to unschedule them when disposing off the PHY?
+  Simulator::Schedule (lrWpanRxParams->duration, &LrWpanPhy::EndRx, this, lrWpanRxParams);
+  ++m_rxTotalNum;
 }
 
-void LrWpanPhy::EndRx ()
+void
+LrWpanPhy::EndRx (Ptr<LrWpanSpectrumSignalParameters> params)
 {
   NS_LOG_FUNCTION (this);
+  NS_ASSERT (params != 0);
+
+  // Calculate whether packet was lost.
   LrWpanSpectrumValueHelper psdHelper;
-  // Calculate whether packet was lost
-  if (m_currentRxPacket.second == true)
+  Ptr<LrWpanSpectrumSignalParameters> currentRxParams = m_currentRxPacket.first;
+  Ptr<const Packet> packet = params->packetBurst->GetPackets ().front ();
+
+  // We are currently receiving a packet.
+  if (m_trxState == IEEE_802_15_4_PHY_BUSY_RX)
     {
-      if (m_currentRxPacket.first != 0)
-        {
-          NS_LOG_DEBUG ("Reception was previously terminated; dropping packet");
-          m_phyRxDropTrace (m_currentRxPacket.first);
-          m_currentRxPacket.first = 0;
-        }
-      else
-        {
-          // TODO: This should never happen, but it does!
-          NS_LOG_UNCOND (this << " Finishing receive of NULL packet!");
-        }
-    }
-  else
-    {
+      NS_ASSERT (currentRxParams && !m_currentRxPacket.second);
+
+      Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets ().front ();
       if (m_errorModel != 0)
         {
-          double sinr = psdHelper.TotalAvgPower (m_rxPsd) / psdHelper.TotalAvgPower (m_noise);
-          Ptr<Packet> p = m_currentRxPacket.first;
-          NS_ASSERT (p != 0);
-          p->AddPacketTag (LrWpanLqiTag (sinr));
+          // How many bits did we receive since the last calculation?
+          double t = (Simulator::Now () - m_rxLastUpdate).ToDouble (Time::MS);
+          uint32_t chunkSize = ceil (t * (GetDataOrSymbolRate (true) / 1000));
+          std::cout << "current signal : " << 10 * log10 (LrWpanSpectrumValueHelper::TotalAvgPower (currentRxParams->psd)) << std::endl;
+          std::cout << "all signals : " << 10 * log10 (LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd ())) << std::endl;
+          std::cout << "noise : " << 10 * log10 (LrWpanSpectrumValueHelper::TotalAvgPower (m_noise)) << std::endl;
+          Ptr<SpectrumValue> interferenceAndNoise = m_signal->GetSignalPsd ();
+          *interferenceAndNoise -= *currentRxParams->psd;
+          *interferenceAndNoise += *m_noise;
+          std::cout << "interference and noise : " << 10 * log10 (LrWpanSpectrumValueHelper::TotalAvgPower (interferenceAndNoise)) << std::endl;
+          double sinr = LrWpanSpectrumValueHelper::TotalAvgPower (currentRxParams->psd) / LrWpanSpectrumValueHelper::TotalAvgPower (interferenceAndNoise);
+          std::cout << "sinr : " << sinr << std::endl;
+          double per = 1.0 - m_errorModel->GetChunkSuccessRate (sinr, chunkSize);
+          std::cout << "per : " << per << std::endl;
 
-          // Simplified calculation; the chunk is the whole packet
-          double per = 1.0 - m_errorModel->GetChunkSuccessRate (sinr, p->GetSize () * 8);
-          if (m_random.GetValue () > per)
+          // TODO: What is the LQI for our model. The SINR is wrong in any case!
+          LrWpanLqiTag tag(sinr);
+          currentPacket->ReplacePacketTag (tag);
+
+          if (m_random.GetValue () < per)
             {
-              NS_LOG_DEBUG ("Reception success for packet: per " << per << " sinr " << sinr);
-              m_phyRxEndTrace (p, sinr);
-              if (!m_pdDataIndicationCallback.IsNull ())
-                {
-                  m_pdDataIndicationCallback (p->GetSize (), p, (uint8_t)sinr);
-                }
-            }
-          else
-            {
-              /* Failure */
-              NS_LOG_DEBUG ("Reception failure for packet per" << per << " sinr " << sinr);
-              m_phyRxEndTrace (p, sinr);
-              m_phyRxDropTrace (p);
+              // The packet was destroyed, drop the packet after reception.
+              m_currentRxPacket.second = true;
             }
         }
       else
         {
+          LrWpanLqiTag tag;
+          currentPacket->ReplacePacketTag (tag);
           NS_LOG_WARN ("Missing ErrorModel");
-          Ptr<Packet> p = m_currentRxPacket.first;
-          p->AddPacketTag (LrWpanLqiTag ());
-          m_phyRxEndTrace (p, 0);
+        }
+    }
+
+  // Update the interference.
+  m_signal->RemoveSignal (params->psd);
+  m_rxLastUpdate = Simulator::Now ();
+  --m_rxTotalNum;
+
+  // If this is the end of the currently received packet, check if reception was successfull.
+  if (currentRxParams == params)
+    {
+      Ptr<Packet> currentPacket = currentRxParams->packetBurst->GetPackets ().front ();
+      NS_ASSERT (currentPacket != 0);
+
+      LrWpanLqiTag tag;
+      currentPacket->PeekPacketTag (tag);
+      m_phyRxEndTrace (currentPacket, tag.Get ());
+
+      if (!m_currentRxPacket.second)
+        {
+          // The packet was successfully received, push it up the stack.
           if (!m_pdDataIndicationCallback.IsNull ())
             {
-              m_pdDataIndicationCallback (p->GetSize (), p, 0);
+              m_pdDataIndicationCallback (currentPacket->GetSize (), currentPacket, tag.Get ());
             }
         }
-
-      m_rxTotalPower = 0;
-      Ptr<Packet> none = 0;
+      else
+        {
+          // The packet was destroyed, drop it.
+          m_phyRxDropTrace (currentPacket);
+        }
+      Ptr<LrWpanSpectrumSignalParameters> none = 0;
       m_currentRxPacket = std::make_pair (none, true);
 
       // We may be waiting to apply a pending state change.
@@ -385,10 +414,7 @@
         }
       else
         {
-          if (m_trxState != IEEE_802_15_4_PHY_TRX_OFF)
-            {
-              ChangeTrxState (IEEE_802_15_4_PHY_RX_ON);
-            }
+          ChangeTrxState (IEEE_802_15_4_PHY_RX_ON);
         }
     }
 }
@@ -499,7 +525,7 @@
   NS_LOG_FUNCTION (this);
   if (m_trxState == IEEE_802_15_4_PHY_RX_ON)
     {
-      m_rxEdPeakPower = m_rxTotalPower;
+      m_rxEdPeakPower = LrWpanSpectrumValueHelper::TotalAvgPower (m_signal->GetSignalPsd());
       Time edTime = Seconds (8.0 / GetDataOrSymbolRate (false));
       m_edRequest = Simulator::Schedule (edTime, &LrWpanPhy::EndEd, this);
     }
@@ -1080,11 +1106,10 @@
 {
   NS_LOG_FUNCTION (this << packet);
 
-  Time txTime = Seconds (0);
   bool isData = true;
+  Time txTime = GetPpduHeaderTxTime ();
 
-  txTime = Seconds (GetPpduHeaderTxTime ()
-                    + packet->GetSize () * 8.0 / GetDataOrSymbolRate (isData));
+  txTime += Time::FromDouble (packet->GetSize () * 8.0 / GetDataOrSymbolRate (isData) * 1000, Time::MS);
 
   return txTime;
 }
@@ -1110,7 +1135,7 @@
   return (rate * 1000.0);
 }
 
-double
+Time
 LrWpanPhy::GetPpduHeaderTxTime (void)
 {
   NS_LOG_FUNCTION (this);
@@ -1124,7 +1149,7 @@
     + ppduHeaderSymbolNumbers[m_phyOption].shrSfd
     + ppduHeaderSymbolNumbers[m_phyOption].phr;
 
-  return totalPpduHdrSymbols / GetDataOrSymbolRate (isData);
+  return Time::FromDouble (totalPpduHdrSymbols / GetDataOrSymbolRate (isData) * 1000, Time::MS);
 }
 
 // IEEE802.15.4-2006 Table 2 in section 6.1.2
--- a/src/lr-wpan/model/lr-wpan-phy.h	Tue Mar 25 23:21:02 2014 +0100
+++ b/src/lr-wpan/model/lr-wpan-phy.h	Thu Mar 27 16:56:15 2014 +0100
@@ -22,6 +22,8 @@
 #ifndef LR_WPAN_PHY_H
 #define LR_WPAN_PHY_H
 
+#include "lr-wpan-interference-helper.h"
+
 #include <ns3/spectrum-phy.h>
 #include <ns3/traced-callback.h>
 #include <ns3/event-id.h>
@@ -378,19 +380,18 @@
   void SetMyPhyOption (void);
   LrWpanPhyOption GetMyPhyOption (void);
   void EndTx ();
-  void EndRx ();
+  void EndRx (Ptr<LrWpanSpectrumSignalParameters> params);
   void EndEd ();
   void EndCca ();
   void EndSetTRXState ();
   Time CalculateTxTime (Ptr<const Packet> packet);
-  double GetPpduHeaderTxTime (void);
+  Time GetPpduHeaderTxTime (void);
   bool ChannelSupported (uint8_t);
   Ptr<MobilityModel> m_mobility;
   Ptr<NetDevice> m_device;
   Ptr<SpectrumChannel> m_channel;
   Ptr<AntennaModel> m_antenna;
   Ptr<SpectrumValue> m_txPsd;
-  Ptr<const SpectrumValue> m_rxPsd;
   Ptr<const SpectrumValue> m_noise;
   Ptr<LrWpanErrorModel> m_errorModel;
   LrWpanPhyPibAttributes m_phyPIBAttributes;
@@ -461,7 +462,9 @@
   double m_rxTotalPower;
   uint32_t m_rxTotalNum;
   double m_rxSensitivity;
-  PacketAndStatus m_currentRxPacket;
+  Ptr<LrWpanInterferenceHelper> m_signal;
+  Time m_rxLastUpdate;
+  std::pair<Ptr<LrWpanSpectrumSignalParameters>, bool>  m_currentRxPacket;
   PacketAndStatus m_currentTxPacket;
 
   EventId m_ccaRequest;
--- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc	Tue Mar 25 23:21:02 2014 +0100
+++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.cc	Thu Mar 27 16:56:15 2014 +0100
@@ -121,7 +121,7 @@
 double
 LrWpanSpectrumValueHelper::TotalAvgPower (Ptr<const SpectrumValue> psd)
 {
-  NS_LOG_FUNCTION (this << psd);
+  NS_LOG_FUNCTION (psd);
   double totalAvgPower = 0.0;
 
   // numerically integrate to get area under psd using
--- a/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h	Tue Mar 25 23:21:02 2014 +0100
+++ b/src/lr-wpan/model/lr-wpan-spectrum-value-helper.h	Thu Mar 27 16:56:15 2014 +0100
@@ -57,7 +57,7 @@
    * \param power spectral density
    * \return total power (using composite trap. rule to numerally integrate
    */
-  double TotalAvgPower (Ptr<const SpectrumValue> psd);
+  static double TotalAvgPower (Ptr<const SpectrumValue> psd);
 
 private:
   double m_noiseFactor;
--- a/src/lr-wpan/test/lr-wpan-error-model-test.cc	Tue Mar 25 23:21:02 2014 +0100
+++ b/src/lr-wpan/test/lr-wpan-error-model-test.cc	Thu Mar 27 16:56:15 2014 +0100
@@ -125,9 +125,9 @@
 
   Simulator::Run ();
 
-  // Test that we received 978 packets out of 1000, at distance of 100 m
+  // Test that we received 173 packets out of 1000, at distance of 100 m
   // with default power of 0
-  NS_TEST_ASSERT_MSG_EQ (GetReceived (), 978, "Model fails");
+  NS_TEST_ASSERT_MSG_EQ (GetReceived (), 173, "Model fails");
 
   Simulator::Destroy ();
 }
--- a/src/lr-wpan/wscript	Tue Mar 25 23:21:02 2014 +0100
+++ b/src/lr-wpan/wscript	Thu Mar 27 16:56:15 2014 +0100
@@ -4,6 +4,7 @@
     obj = bld.create_ns3_module('lr-wpan', ['core', 'network', 'mobility', 'spectrum', 'propagation'])
     obj.source = [
         'model/lr-wpan-error-model.cc',
+        'model/lr-wpan-interference-helper.cc',
         'model/lr-wpan-phy.cc',
         'model/lr-wpan-mac.cc',
         'model/lr-wpan-mac-header.cc',
@@ -28,6 +29,7 @@
     headers.module = 'lr-wpan'
     headers.source = [
         'model/lr-wpan-error-model.h',
+        'model/lr-wpan-interference-helper.h',
         'model/lr-wpan-phy.h',
         'model/lr-wpan-mac.h',
         'model/lr-wpan-mac-header.h',