src/devices/wifi/yans-wifi-phy.cc
changeset 3902 9e048e073cf0
parent 3900 1687492ff059
child 3905 99c9346b5d71
--- a/src/devices/wifi/yans-wifi-phy.cc	Thu Jun 12 12:07:50 2008 -0700
+++ b/src/devices/wifi/yans-wifi-phy.cc	Thu Jun 12 12:28:36 2008 -0700
@@ -23,6 +23,7 @@
 #include "wifi-mode.h"
 #include "wifi-preamble.h"
 #include "wifi-phy-state-helper.h"
+#include "error-rate-model.h"
 #include "ns3/simulator.h"
 #include "ns3/packet.h"
 #include "ns3/random-variable.h"
@@ -212,6 +213,7 @@
 {
   NS_LOG_FUNCTION (this);
   m_state = CreateObject<WifiPhyStateHelper> ();
+  m_errorRateModel = Create<ErrorRateModel> ();
 }
 
 YansWifiPhy::~YansWifiPhy ()
@@ -484,7 +486,7 @@
     {
       NS_ASSERT (high >= low);
       double middle = low + (high - low) / 2;
-      if ((1 - GetChunkSuccessRate (txMode, middle, 1)) > ber) 
+      if ((1 - m_errorRateModel->GetChunkSuccessRate (txMode, middle, 1)) > ber) 
         {
           low = middle;
         } 
@@ -518,7 +520,7 @@
     std::cout <<snr<<" ";
     for (uint8_t i = 0; i < GetNModes (); i++) {
       WifiMode mode = GetMode (i);
-      double ber = 1-GetChunkSuccessRate (mode,snr, 2000*8);
+      double ber = 1-m_errorRateModel->GetChunkSuccessRate (mode,snr, 2000*8);
       std::cout <<ber<< " ";
     }
     std::cout << std::endl;
@@ -701,236 +703,6 @@
 }
 
 
-
-/**
- * Stuff specific to the BER model here.
- */
-double 
-YansWifiPhy::Log2 (double val) const
-{
-  return log(val) / log(2.0);
-}
-double 
-YansWifiPhy::GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const
-{
-  double EbNo = snr * signalSpread / phyRate;
-  double z = sqrt(EbNo);
-  double ber = 0.5 * erfc(z);
-  NS_LOG_INFO ("bpsk snr="<<snr<<" ber="<<ber);
-  return ber;
-}
-double 
-YansWifiPhy::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const
-{
-  double EbNo = snr * signalSpread / phyRate;
-  double z = sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
-  double z1 = ((1.0 - 1.0 / sqrt (m)) * erfc (z)) ;
-  double z2 = 1 - pow ((1-z1), 2.0);
-  double ber = z2 / Log2 (m);
-  NS_LOG_INFO ("Qam m="<<m<<" rate=" << phyRate << " snr="<<snr<<" ber="<<ber);
-  return ber;
-}
-uint32_t
-YansWifiPhy::Factorial (uint32_t k) const
-{
-  uint32_t fact = 1;
-  while (k > 0) 
-    {
-      fact *= k;
-      k--;
-    }
-  return fact;
-}
-double 
-YansWifiPhy::Binomial (uint32_t k, double p, uint32_t n) const
-{
-  double retval = Factorial (n) / (Factorial (k) * Factorial (n-k)) * pow (p, k) * pow (1-p, n-k);
-  return retval;
-}
-double 
-YansWifiPhy::CalculatePdOdd (double ber, unsigned int d) const
-{
-  NS_ASSERT ((d % 2) == 1);
-  unsigned int dstart = (d + 1) / 2;
-  unsigned int dend = d;
-  double pd = 0;
-
-  for (unsigned int i = dstart; i < dend; i++) 
-    {
-      pd += Binomial (i, ber, d);
-    }
-  return pd;
-}
-double 
-YansWifiPhy::CalculatePdEven (double ber, unsigned int d) const
-{
-  NS_ASSERT ((d % 2) == 0);
-  unsigned int dstart = d / 2 + 1;
-  unsigned int dend = d;
-  double pd = 0;
-
-  for (unsigned int i = dstart; i < dend; i++)
-    {
-      pd +=  Binomial (i, ber, d);
-    }
-  pd += 0.5 * Binomial (d / 2, ber, d);
-
-  return pd;
-}
-
-double 
-YansWifiPhy::CalculatePd (double ber, unsigned int d) const
-{
-  double pd;
-  if ((d % 2) == 0) 
-    {
-      pd = CalculatePdEven (ber, d);
-    } 
-  else 
-    {
-      pd = CalculatePdOdd (ber, d);
-    }
-  return pd;
-}
-
-double
-YansWifiPhy::GetFecBpskBer (double snr, double nbits, 
-                         uint32_t signalSpread, uint32_t phyRate,
-                         uint32_t dFree, uint32_t adFree) const
-{
-  double ber = GetBpskBer (snr, signalSpread, phyRate);
-  if (ber == 0.0) 
-    {
-      return 1.0;
-    }
-  double pd = CalculatePd (ber, dFree);
-  double pmu = adFree * pd;
-  pmu = std::min (pmu, 1.0);
-  double pms = pow (1 - pmu, nbits);
-  return pms;
-}
-
-double
-YansWifiPhy::GetFecQamBer (double snr, uint32_t nbits, 
-                       uint32_t signalSpread,
-                       uint32_t phyRate,
-                       uint32_t m, uint32_t dFree,
-                       uint32_t adFree, uint32_t adFreePlusOne) const
-{
-  double ber = GetQamBer (snr, m, signalSpread, phyRate);
-  if (ber == 0.0) 
-    {
-      return 1.0;
-    }
-  /* first term */
-  double pd = CalculatePd (ber, dFree);
-  double pmu = adFree * pd;
-  /* second term */
-  pd = CalculatePd (ber, dFree + 1);
-  pmu += adFreePlusOne * pd;
-  pmu = std::min (pmu, 1.0);
-  double pms = pow (1 - pmu, nbits);
-  return pms;
-}
-
-double 
-YansWifiPhy::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
-{
-  if (mode.GetUid () == g_6mba.GetUid ())
-    {
-      return GetFecBpskBer (snr, 
-                            nbits,
-                            mode.GetBandwidth (), // signal spread
-                            mode.GetPhyRate (), // phy rate
-                            10, // dFree
-                            11 // adFree
-                            );      
-    }
-  else if (mode.GetUid () == g_9mba.GetUid ())
-    {
-      return GetFecBpskBer (snr, 
-                            nbits,
-                            mode.GetBandwidth (), // signal spread
-                            mode.GetPhyRate (), // phy rate
-                            5, // dFree
-                            8 // adFree
-                            );
-    }
-  else if (mode.GetUid () == g_12mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           4,  // m 
-                           10, // dFree
-                           11, // adFree
-                           0   // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_18mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           4, // m
-                           5, // dFree
-                           8, // adFree
-                           31 // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_24mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           16, // m
-                           10, // dFree
-                           11, // adFree
-                           0   // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_36mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           16, // m
-                           5,  // dFree
-                           8,  // adFree
-                           31  // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_48mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           64, // m
-                           6,  // dFree
-                           1,  // adFree
-                           16  // adFreePlusOne
-                           );
-    }
-  else if (mode.GetUid () == g_54mba.GetUid ())
-    {
-      return GetFecQamBer (snr, 
-                           nbits,
-                           mode.GetBandwidth (), // signal spread
-                           mode.GetPhyRate (), // phy rate
-                           64, // m
-                           5,  // dFree
-                           8,  // adFree
-                           31  // adFreePlusOne
-                           );
-    }
-  return 0;
-}
-
 double
 YansWifiPhy::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
 {
@@ -987,7 +759,7 @@
   }
   uint32_t rate = mode.GetPhyRate ();
   uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
-  double csr = GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
+  double csr = m_errorRateModel->GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
   return csr;
 }
 
@@ -1114,7 +886,7 @@
    */
   double per = CalculatePer (event, &ni);
   NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
-                ", ber="<<(1-GetChunkSuccessRate (event->GetPayloadMode (), snr, 1))<<
+                ", ber="<<(1-m_errorRateModel->GetChunkSuccessRate (event->GetPayloadMode (), snr, 1))<<
                 ", snr="<<snr<<", per="<<per<<", size="<<packet->GetSize ());
   
   if (m_random.GetValue () > per)