--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/error-rate-model.cc Thu Jun 12 12:28:36 2008 -0700
@@ -0,0 +1,249 @@
+#include "error-rate-model.h"
+#include "wifi-phy.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("ErrorRateModel");
+
+namespace ns3 {
+
+TypeId
+ErrorRateModel::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::ErrorRateModel")
+ .SetParent<Object> ()
+ .AddConstructor<ErrorRateModel> ()
+ ;
+ return tid;
+}
+
+ErrorRateModel::ErrorRateModel ()
+{}
+
+
+double
+ErrorRateModel::Log2 (double val) const
+{
+ return log(val) / log(2.0);
+}
+double
+ErrorRateModel::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
+ErrorRateModel::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
+ErrorRateModel::Factorial (uint32_t k) const
+{
+ uint32_t fact = 1;
+ while (k > 0)
+ {
+ fact *= k;
+ k--;
+ }
+ return fact;
+}
+double
+ErrorRateModel::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
+ErrorRateModel::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
+ErrorRateModel::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
+ErrorRateModel::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
+ErrorRateModel::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
+ErrorRateModel::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
+ErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
+{
+ if (mode == WifiPhy::g_6mba)
+ {
+ return GetFecBpskBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 10, // dFree
+ 11 // adFree
+ );
+ }
+ else if (mode == WifiPhy::g_9mba)
+ {
+ return GetFecBpskBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 5, // dFree
+ 8 // adFree
+ );
+ }
+ else if (mode == WifiPhy::g_12mba)
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 4, // m
+ 10, // dFree
+ 11, // adFree
+ 0 // adFreePlusOne
+ );
+ }
+ else if (mode == WifiPhy::g_18mba)
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 4, // m
+ 5, // dFree
+ 8, // adFree
+ 31 // adFreePlusOne
+ );
+ }
+ else if (mode == WifiPhy::g_24mba)
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 16, // m
+ 10, // dFree
+ 11, // adFree
+ 0 // adFreePlusOne
+ );
+ }
+ else if (mode == WifiPhy::g_36mba)
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 16, // m
+ 5, // dFree
+ 8, // adFree
+ 31 // adFreePlusOne
+ );
+ }
+ else if (mode == WifiPhy::g_48mba)
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 64, // m
+ 6, // dFree
+ 1, // adFree
+ 16 // adFreePlusOne
+ );
+ }
+ else if (mode == WifiPhy::g_54mba)
+ {
+ return GetFecQamBer (snr,
+ nbits,
+ mode.GetBandwidth (), // signal spread
+ mode.GetPhyRate (), // phy rate
+ 64, // m
+ 5, // dFree
+ 8, // adFree
+ 31 // adFreePlusOne
+ );
+ }
+ return 0;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/error-rate-model.h Thu Jun 12 12:28:36 2008 -0700
@@ -0,0 +1,41 @@
+#ifndef ERROR_RATE_MODEL_H
+#define ERROR_RATE_MODEL_H
+
+#include <stdint.h>
+#include "wifi-mode.h"
+#include "ns3/object.h"
+
+namespace ns3 {
+
+class ErrorRateModel : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+
+ ErrorRateModel ();
+
+ double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
+
+private:
+ double Log2 (double val) const;
+ double GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const;
+ double GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const;
+ uint32_t Factorial (uint32_t k) const;
+ double Binomial (uint32_t k, double p, uint32_t n) const;
+ double CalculatePdOdd (double ber, unsigned int d) const;
+ double CalculatePdEven (double ber, unsigned int d) const;
+ double CalculatePd (double ber, unsigned int d) const;
+ double GetFecBpskBer (double snr, double nbits,
+ uint32_t signalSpread, uint32_t phyRate,
+ uint32_t dFree, uint32_t adFree) const;
+ double 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;
+};
+
+
+} // namespace ns3
+
+#endif /* ERROR_RATE_MODEL_H */
--- a/src/devices/wifi/wscript Thu Jun 12 12:07:50 2008 -0700
+++ b/src/devices/wifi/wscript Thu Jun 12 12:28:36 2008 -0700
@@ -12,6 +12,7 @@
'ssid.cc',
'wifi-phy.cc',
'wifi-phy-state-helper.cc',
+ 'error-rate-model.cc',
'yans-wifi-phy.cc',
'yans-wifi-channel.cc',
'wifi-mac-header.cc',
--- 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)
--- a/src/devices/wifi/yans-wifi-phy.h Thu Jun 12 12:07:50 2008 -0700
+++ b/src/devices/wifi/yans-wifi-phy.h Thu Jun 12 12:28:36 2008 -0700
@@ -44,6 +44,7 @@
class RxEvent;
class YansWifiChannel;
class WifiPhyStateHelper;
+class ErrorRateModel;
/**
@@ -146,23 +147,6 @@
double CalculateChunkSuccessRate (double snir, Time delay, WifiMode mode) const;
double CalculatePer (Ptr<const RxEvent> event, NiChanges *ni) const;
void EndSync (Ptr<Packet> packet, Ptr<RxEvent> event);
- double Log2 (double val) const;
- double GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const;
- double GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const;
- uint32_t Factorial (uint32_t k) const;
- double Binomial (uint32_t k, double p, uint32_t n) const;
- double CalculatePdOdd (double ber, unsigned int d) const;
- double CalculatePdEven (double ber, unsigned int d) const;
- double CalculatePd (double ber, unsigned int d) const;
- double GetFecBpskBer (double snr, double nbits,
- uint32_t signalSpread, uint32_t phyRate,
- uint32_t dFree, uint32_t adFree) const;
- double 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 GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
private:
uint64_t m_txPrepareDelayUs;
uint64_t m_plcpLongPreambleDelayUs;
@@ -187,6 +171,7 @@
UniformVariable m_random;
WifiPhyStandard m_standard;
Ptr<WifiPhyStateHelper> m_state;
+ Ptr<ErrorRateModel> m_errorRateModel;
};
} // namespace ns3