--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/wifi-clear-channel-cmu.cc Thu May 28 20:10:27 2009 +0200
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 The Boeing Company
+ *
+ * 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: Guangyu Pei <guangyu.pei@boeing.com>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/common-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/contrib-module.h"
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+
+NS_LOG_COMPONENT_DEFINE ("Main");
+
+using namespace ns3;
+
+class Experiment
+{
+public:
+ Experiment ();
+ Experiment (std::string name);
+ uint32_t Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
+ const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel);
+private:
+ void ReceivePacket (Ptr<Socket> socket);
+ void SetPosition (Ptr<Node> node, Vector position);
+ Vector GetPosition (Ptr<Node> node);
+ Ptr<Socket> SetupPacketReceive (Ptr<Node> node);
+ void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
+ uint32_t pktCount, Time pktInterval );
+
+ uint32_t m_pktsTotal;
+ Gnuplot2dDataset m_output;
+};
+
+Experiment::Experiment ()
+{}
+
+Experiment::Experiment (std::string name)
+ : m_output (name)
+{
+ m_output.SetStyle (Gnuplot2dDataset::LINES);
+}
+
+void
+Experiment::SetPosition (Ptr<Node> node, Vector position)
+{
+ Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
+ mobility->SetPosition (position);
+}
+
+Vector
+Experiment::GetPosition (Ptr<Node> node)
+{
+ Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
+ return mobility->GetPosition ();
+}
+
+void
+Experiment::ReceivePacket (Ptr<Socket> socket)
+{
+ Ptr<Packet> packet;
+ while (packet = socket->Recv ())
+ {
+ m_pktsTotal ++;
+ }
+}
+
+Ptr<Socket>
+Experiment::SetupPacketReceive (Ptr<Node> node)
+{
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ Ptr<Socket> sink = Socket::CreateSocket (node, tid);
+ InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
+ sink->Bind (local);
+ sink->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
+ return sink;
+}
+
+void
+Experiment::GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
+ uint32_t pktCount, Time pktInterval )
+{
+ if (pktCount > 0)
+ {
+ socket->Send (Create<Packet> (pktSize));
+ Simulator::Schedule (pktInterval, &Experiment::GenerateTraffic, this,
+ socket, pktSize,pktCount-1, pktInterval);
+ }
+ else
+ {
+ socket->Close ();
+ }
+}
+
+uint32_t
+Experiment::Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy,
+ const NqosWifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel)
+{
+ m_pktsTotal = 0;
+
+ NodeContainer c;
+ c.Create (2);
+
+ InternetStackHelper internet;
+ internet.Install (c);
+
+ YansWifiPhyHelper phy = wifiPhy;
+ phy.SetChannel (wifiChannel.Create ());
+
+ NqosWifiMacHelper mac = wifiMac;
+ NetDeviceContainer devices = wifi.Install (phy, mac, c);
+
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (c);
+
+ Ipv4AddressHelper ipv4;
+ NS_LOG_INFO ("Assign IP Addresses.");
+ ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer i = ipv4.Assign (devices);
+
+ Ptr<Socket> recvSink = SetupPacketReceive (c.Get (0));
+
+ TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+ Ptr<Socket> source = Socket::CreateSocket (c.Get (1), tid);
+ InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), 80);
+ source->Connect (remote);
+ uint32_t packetSize = 1014;
+ uint32_t maxPacketCount = 200;
+ Time interPacketInterval = Seconds (1.);
+ Simulator::Schedule (Seconds (1.0), &Experiment::GenerateTraffic,
+ this, source, packetSize, maxPacketCount,interPacketInterval);
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+
+ return m_pktsTotal;
+}
+
+int main (int argc, char *argv[])
+{
+ std::ofstream outfile ("clear-channel.plt");
+ std::vector <std::string> modes;
+
+ modes.push_back ("wifib-1mbs");
+ modes.push_back ("wifib-2mbs");
+ modes.push_back ("wifib-5.5mbs");
+ modes.push_back ("wifib-11mbs");
+ // disable fragmentation
+ Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
+ Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ Gnuplot gnuplot = Gnuplot ("clear-channel.eps");
+
+ for (uint32_t i = 0; i < modes.size(); i++)
+ {
+ std::cout << modes[i] << std::endl;
+ Gnuplot2dDataset dataset (modes[i]);
+
+ for (double rss = -102.0; rss <= -80.0; rss += 0.5)
+ {
+ Experiment experiment;
+ dataset.SetStyle (Gnuplot2dDataset::LINES);
+
+ WifiHelper wifi;
+ NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+ Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
+ StringValue (modes[i]));
+ wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
+ "DataMode",StringValue(modes[i]),
+ "ControlMode",StringValue(modes[i]));
+ wifiMac.SetType ("ns3::AdhocWifiMac");
+
+ YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+ YansWifiChannelHelper wifiChannel ;
+ wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+ wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",DoubleValue(rss));
+
+
+ NS_LOG_DEBUG (modes[i]);
+ experiment = Experiment (modes[i]);
+ wifiPhy.Set ("Standard", StringValue ("802.11b") );
+ wifiPhy.Set ("EnergyDetectionThreshold", DoubleValue (-110.0) );
+ wifiPhy.Set ("CcaMode1Threshold", DoubleValue (-110.0) );
+ wifiPhy.Set ("TxPowerStart", DoubleValue (15.0) );
+ wifiPhy.Set ("RxGain", DoubleValue (0) );
+ wifiPhy.Set ("RxNoiseFigure", DoubleValue (7) );
+ uint32_t pktsRecvd = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
+ dataset.Add (rss, pktsRecvd);
+ }
+
+ gnuplot.AddDataset (dataset);
+ }
+ gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
+ gnuplot.SetLegend ("RSS(dBm)", "Number of packets received");
+ gnuplot.SetExtra ("set xrange [-102:-83]");
+ gnuplot.GenerateOutput (outfile);
+ outfile.close ();
+
+ return 0;
+}
--- a/examples/wscript Thu May 28 20:09:28 2009 +0200
+++ b/examples/wscript Thu May 28 20:10:27 2009 +0200
@@ -116,6 +116,10 @@
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'wifi-adhoc.cc'
+ obj = bld.create_ns3_program('wifi-clear-channel-cmu',
+ ['core', 'simulator', 'mobility', 'wifi'])
+ obj.source = 'wifi-clear-channel-cmu.cc'
+
obj = bld.create_ns3_program('wifi-ap',
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'wifi-ap.cc'
--- a/src/devices/wifi/interference-helper.cc Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/interference-helper.cc Thu May 28 20:10:27 2009 +0200
@@ -123,7 +123,7 @@
****************************************************************/
InterferenceHelper::InterferenceHelper ()
- : m_80211a (false),
+ : m_80211_standard (WIFI_PHY_STANDARD_80211a),
m_errorRateModel (0)
{}
InterferenceHelper::~InterferenceHelper ()
@@ -227,12 +227,25 @@
Time
InterferenceHelper::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const
{
- NS_ASSERT (m_80211a);
uint64_t delay = 0;
- delay += m_plcpLongPreambleDelayUs;
- // symbol duration is 4us
- delay += 4;
- delay += lrint (ceil ((size * 8.0 + 16.0 + 6.0) / payloadMode.GetDataRate () / 4e-6) * 4);
+ switch (m_80211_standard)
+ {
+ case WIFI_PHY_STANDARD_80211a:
+ case WIFI_PHY_STANDARD_holland:
+ delay += m_plcpLongPreambleDelayUs;
+ // symbol duration is 4us
+ delay += 4;
+ delay += lrint (ceil ((size * 8.0 + 16.0 + 6.0) / payloadMode.GetDataRate () / 4e-6) * 4);
+ break;
+ case WIFI_PHY_STANDARD_80211b:
+ delay += m_plcpLongPreambleDelayUs;
+ delay += lrint (ceil ((size * 8.0 + 48.0) / payloadMode.GetDataRate () / 4e-6) * 4);
+ break;
+ default:
+ NS_ASSERT (false);
+ break;
+ }
+
return MicroSeconds (delay);
}
@@ -240,7 +253,7 @@
InterferenceHelper::Configure80211aParameters (void)
{
NS_LOG_FUNCTION (this);
- m_80211a = true;
+ m_80211_standard = WIFI_PHY_STANDARD_80211a;
m_plcpLongPreambleDelayUs = 16;
m_plcpShortPreambleDelayUs = 16;
m_longPlcpHeaderMode = WifiPhy::Get6mba ();
@@ -250,6 +263,20 @@
m_maxPacketDuration = CalculateTxDuration (4095, WifiPhy::Get6mba (), WIFI_PREAMBLE_LONG);
}
+void
+InterferenceHelper::Configure80211bParameters (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_80211_standard = WIFI_PHY_STANDARD_80211b;
+ m_plcpLongPreambleDelayUs = 144;
+ m_plcpShortPreambleDelayUs = 144; // fixed preamable for 802.11b
+ m_longPlcpHeaderMode = WifiPhy::Get1mbb ();
+ m_shortPlcpHeaderMode = WifiPhy::Get1mbb ();
+ // PLCP Header: signal 8, service 8, length 16, CRC 16 bits
+ m_plcpHeaderLength = 8 + 8 + 16 + 16;
+ m_maxPacketDuration = CalculateTxDuration (4095, WifiPhy::Get1mbb (), WIFI_PREAMBLE_LONG);
+}
+
void
InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> event)
{
--- a/src/devices/wifi/interference-helper.h Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/interference-helper.h Thu May 28 20:10:27 2009 +0200
@@ -25,6 +25,7 @@
#include <list>
#include "wifi-mode.h"
#include "wifi-preamble.h"
+#include "wifi-phy-standard.h"
#include "ns3/nstime.h"
#include "ns3/ref-count-base.h"
@@ -69,6 +70,7 @@
~InterferenceHelper ();
void Configure80211aParameters (void);
+ void Configure80211bParameters (void);
void SetNoiseFigure (double value);
void SetErrorRateModel (Ptr<ErrorRateModel> rate);
@@ -120,7 +122,7 @@
Time m_maxPacketDuration;
double m_noiseFigure; /**< noise figure (linear) */
Events m_events;
- bool m_80211a;
+ enum WifiPhyStandard m_80211_standard;
Ptr<ErrorRateModel> m_errorRateModel;
};
--- a/src/devices/wifi/wifi-mode.cc Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/wifi-mode.cc Thu May 28 20:10:27 2009 +0200
@@ -165,7 +165,44 @@
item->isMandatory = isMandatory;
return WifiMode (uid);
}
-
+WifiMode
+WifiModeFactory::CreateDbpsk (std::string uniqueName,
+ bool isMandatory,
+ uint32_t bandwidth,
+ uint32_t dataRate,
+ uint32_t phyRate)
+{
+ WifiModeFactory *factory = GetFactory ();
+ uint32_t uid = factory->AllocateUid (uniqueName);
+ WifiModeItem *item = factory->Get (uid);
+ item->uniqueUid = uniqueName;
+ item->bandwidth = bandwidth;
+ item->dataRate = dataRate;
+ item->phyRate = phyRate;
+ item->modulation = WifiMode::DBPSK;
+ item->constellationSize = 2;
+ item->isMandatory = isMandatory;
+ return WifiMode (uid);
+}
+WifiMode
+WifiModeFactory::CreateDqpsk (std::string uniqueName,
+ bool isMandatory,
+ uint32_t bandwidth,
+ uint32_t dataRate,
+ uint32_t phyRate)
+{
+ WifiModeFactory *factory = GetFactory ();
+ uint32_t uid = factory->AllocateUid (uniqueName);
+ WifiModeItem *item = factory->Get (uid);
+ item->uniqueUid = uniqueName;
+ item->bandwidth = bandwidth;
+ item->dataRate = dataRate;
+ item->phyRate = phyRate;
+ item->modulation = WifiMode::DQPSK;
+ item->constellationSize = 4;
+ item->isMandatory = isMandatory;
+ return WifiMode (uid);
+}
bool
WifiModeFactory::Search (std::string name, WifiMode *mode)
{
--- a/src/devices/wifi/wifi-mode.h Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/wifi-mode.h Thu May 28 20:10:27 2009 +0200
@@ -41,6 +41,8 @@
public:
enum ModulationType {
BPSK,
+ DBPSK,
+ DQPSK,
QAM
};
@@ -170,6 +172,40 @@
uint32_t phyRate,
uint8_t constellationSize);
+ /**
+ * \param uniqueName the name of the associated WifiMode. This name
+ * must be unique accross _all_ instances.
+ * \param isMandatory true if this WifiMode is mandatory, false otherwise.
+ * \param bandwidth the bandwidth (Hz) of the signal generated when the
+ * associated WifiMode is used.
+ * \param dataRate the rate (bits/second) at which the user data is transmitted
+ * \param phyRate the rate (bits/second) at which the encoded user data is transmitted
+ * The phyRate includes FEC so, is typically higher than the dataRate.
+ *
+ * Create a DBPSK WifiMode.
+ */
+ static WifiMode CreateDbpsk (std::string uniqueName,
+ bool isMandatory,
+ uint32_t bandwidth,
+ uint32_t dataRate,
+ uint32_t phyRate);
+ /**
+ * \param uniqueName the name of the associated WifiMode. This name
+ * must be unique accross _all_ instances.
+ * \param isMandatory true if this WifiMode is mandatory, false otherwise.
+ * \param bandwidth the bandwidth (Hz) of the signal generated when the
+ * associated WifiMode is used.
+ * \param dataRate the rate (bits/second) at which the user data is transmitted
+ * \param phyRate the rate (bits/second) at which the encoded user data is transmitted
+ * The phyRate includes FEC so, is typically higher than the dataRate.
+ *
+ * Create a DQPSK WifiMode.
+ */
+ static WifiMode CreateDqpsk (std::string uniqueName,
+ bool isMandatory,
+ uint32_t bandwidth,
+ uint32_t dataRate,
+ uint32_t phyRate);
private:
friend class WifiMode;
friend std::istream & operator >> (std::istream &is, WifiMode &mode);
--- a/src/devices/wifi/wifi-phy-standard.h Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/wifi-phy-standard.h Thu May 28 20:10:27 2009 +0200
@@ -24,6 +24,7 @@
enum WifiPhyStandard {
WIFI_PHY_STANDARD_80211a,
+ WIFI_PHY_STANDARD_80211b,
WIFI_PHY_STANDARD_holland
};
--- a/src/devices/wifi/wifi-phy.cc Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/wifi-phy.cc Thu May 28 20:10:27 2009 +0200
@@ -199,6 +199,43 @@
m_phyPromiscSnifferTrace (packet);
}
+WifiMode
+WifiPhy::Get1mbb (void)
+{
+ static WifiMode mode = WifiModeFactory::CreateDbpsk ("wifib-1mbs",
+ true,
+ 22000000, 1000000, 1000000);
+ return mode;
+}
+
+WifiMode
+WifiPhy::Get2mbb (void)
+{
+ static WifiMode mode = WifiModeFactory::CreateDqpsk ("wifib-2mbs",
+ true,
+ 22000000, 2000000, 2000000);
+ return mode;
+}
+
+WifiMode
+WifiPhy::Get5_5mbb (void)
+{
+ static WifiMode mode = WifiModeFactory::CreateDqpsk ("wifib-5.5mbs",
+ true,
+ 22000000, 5500000, 5500000);
+ return mode;
+}
+
+WifiMode
+WifiPhy::Get11mbb (void)
+{
+ static WifiMode mode = WifiModeFactory::CreateDqpsk ("wifib-11mbs",
+ true,
+ 22000000, 11000000, 11000000);
+ return mode;
+}
+
+
} // namespace ns3
namespace {
@@ -215,6 +252,10 @@
ns3::WifiPhy::Get36mba ();
ns3::WifiPhy::Get48mba ();
ns3::WifiPhy::Get54mba ();
+ ns3::WifiPhy::Get1mbb ();
+ ns3::WifiPhy::Get2mbb ();
+ ns3::WifiPhy::Get5_5mbb ();
+ ns3::WifiPhy::Get11mbb ();
}
} g_constructor;
}
--- a/src/devices/wifi/wifi-phy.h Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/wifi-phy.h Thu May 28 20:10:27 2009 +0200
@@ -252,6 +252,11 @@
static WifiMode Get36mba (void);
static WifiMode Get48mba (void);
static WifiMode Get54mba (void);
+ static WifiMode Get1mbb (void);
+ static WifiMode Get2mbb (void);
+ static WifiMode Get5_5mbb (void);
+ static WifiMode Get11mbb (void);
+
/**
* Public method used to fire a PhyTxBegin trace. Implemented for encapsulation
--- a/src/devices/wifi/wscript Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/wscript Thu May 28 20:10:27 2009 +0200
@@ -1,5 +1,12 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+def configure(conf):
+ have_gsl = conf.pkg_check_modules('GSL', 'gsl', mandatory=False)
+ conf.env['ENABLE_GSL'] = have_gsl
+ conf.report_optional_feature("GSL", "GNU Scientific Library (GSL)",
+ conf.env['ENABLE_GSL'],
+ "GSL not found")
+
def build(bld):
obj = bld.create_ns3_module('wifi', ['node'])
obj.source = [
@@ -100,6 +107,12 @@
'qos-tag.h',
]
+ if bld.env['ENABLE_GSL']:
+ obj.uselib = 'GSL GSLCBLAS M'
+ obj.env.append_value('CXXDEFINES', "ENABLE_GSL")
+
obj = bld.create_ns3_program('wifi-phy-test',
['core', 'simulator', 'mobility', 'node', 'wifi'])
obj.source = 'wifi-phy-test.cc'
+
+
--- a/src/devices/wifi/yans-error-rate-model.cc Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/yans-error-rate-model.cc Thu May 28 20:10:27 2009 +0200
@@ -263,7 +263,159 @@
31 // adFreePlusOne
);
}
+ else if (mode == WifiPhy::Get1mbb ())
+ {
+ return Get80211bDsssDbpskSuccessRate (snr,nbits);
+ }
+ else if (mode == WifiPhy::Get2mbb ())
+ {
+ return Get80211bDsssDqpskSuccessRate (snr,nbits);
+ }
+ else if (mode == WifiPhy::Get5_5mbb ())
+ {
+ return Get80211bDsssDqpskCck5_5SuccessRate (snr,nbits);
+ }
+ else if (mode == WifiPhy::Get11mbb ())
+ {
+ return Get80211bDsssDqpskCck11SuccessRate (snr,nbits);
+ }
return 0;
}
+// 802.11b ber based on "Wireless Network Coexistence: Wireless
+// LAN in the 21st Century" by Robert Morrow page 187
+double
+YansErrorRateModel::DqpskFunction (double x) const
+{
+ return ((sqrt (2.0) + 1.0) / sqrt (8.0*3.1415926*sqrt (2.0)))
+ *(1.0/sqrt (x))
+ *exp ( - (2.0 - sqrt (2.0)) * x) ;
+}
+
+double
+YansErrorRateModel::Get80211bDsssDbpskSuccessRate (double sinr, uint32_t nbits) const
+{
+ double EbN0 = sinr * 22000000.0 / 1000000.0; // 1 bit per symbol with 1 MSPS
+ double ber = 0.5 * exp (-EbN0);
+ return pow ((1.0 - ber), nbits);
+}
+
+double
+YansErrorRateModel::Get80211bDsssDqpskSuccessRate (double sinr,uint32_t nbits) const
+{
+ double EbN0 = sinr * 22000000.0 / 1000000.0 / 2.0; // 2 bits per symbol, 1 MSPS
+ double ber = DqpskFunction (EbN0);
+ return pow ((1.0 - ber), nbits);
+}
+
+double
+YansErrorRateModel::Get80211bDsssDqpskCck5_5SuccessRate (double sinr,uint32_t nbits) const
+{
+#ifdef ENABLE_GSL
+ // symbol error probability
+ double EbN0 = sinr * 22000000.0 / 1375000.0 / 4.0;
+ double sep = SymbolErrorProb16Cck (4.0*EbN0/2.0);
+ return pow (1.0-sep,nbits/4.0);
+#else
+ NS_LOG_WARN ("Running a 802.11b CCK Matlab model less accurate than GSL model");
+ // The matlab model
+ double ber;
+ if (sinr > WLAN_SIR_PERFECT)
+ {
+ ber = 0.0 ;
+ }
+ else if (sinr < WLAN_SIR_IMPOSSIBLE)
+ {
+ ber = 0.5;
+ }
+ else
+ { // fitprops.coeff from matlab berfit
+ double a1 = 5.3681634344056195e-001;
+ double a2 = 3.3092430025608586e-003;
+ double a3 = 4.1654372361004000e-001;
+ double a4 = 1.0288981434358866e+000;
+ ber = a1 * exp (-(pow ((sinr-a2)/a3,a4)));
+ }
+ return pow ((1.0 - ber), nbits);
+#endif
+}
+
+double
+YansErrorRateModel::Get80211bDsssDqpskCck11SuccessRate (double sinr,uint32_t nbits) const
+{
+#ifdef ENABLE_GSL
+ // symbol error probability
+ double EbN0 = sinr * 22000000.0 / 1375000.0 / 8.0;
+ double sep = SymbolErrorProb256Cck (8.0*EbN0/2.0);
+ return pow (1.0-sep,nbits/8.0);
+#else
+ NS_LOG_WARN ("Running a 802.11b CCK Matlab model less accurate than GSL model");
+ // The matlab model
+ double ber;
+ if (sinr > WLAN_SIR_PERFECT)
+ {
+ ber = 0.0 ;
+ }
+ else if (sinr < WLAN_SIR_IMPOSSIBLE)
+ {
+ ber = 0.5;
+ }
+ else
+ { // fitprops.coeff from matlab berfit
+ double a1 = 7.9056742265333456e-003;
+ double a2 = -1.8397449399176360e-001;
+ double a3 = 1.0740689468707241e+000;
+ double a4 = 1.0523316904502553e+000;
+ double a5 = 3.0552298746496687e-001;
+ double a6 = 2.2032715128698435e+000;
+ ber = (a1*sinr*sinr+a2*sinr+a3)/(sinr*sinr*sinr+a4*sinr*sinr+a5*sinr+a6);
+ }
+ return pow ((1.0 - ber), nbits);
+#endif
+}
+
+#ifdef ENABLE_GSL
+double
+IntegralFunction (double x, void *params)
+{
+ double beta = ((FunctionParameters *) params)->beta;
+ double n = ((FunctionParameters *) params)->n;
+ double IntegralFunction = pow (2*gsl_cdf_ugaussian_P (x+ beta) - 1, n-1)
+ * exp (-x*x/2.0) / sqrt (2.0 * M_PI);
+ return IntegralFunction;
+}
+
+double
+YansErrorRateModel::SymbolErrorProb16Cck (double e2) const
+{
+ double sep;
+ double error;
+
+ FunctionParameters params;
+ params.beta = sqrt (2.0*e2);
+ params.n = 8.0;
+
+ gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
+
+ gsl_function F;
+ F.function = &IntegralFunction;
+ F.params = ¶ms;
+
+ gsl_integration_qagiu (&F,-params.beta, 0, 1e-7, 1000, w, &sep, &error);
+ gsl_integration_workspace_free (w);
+ if (error == 0.0)
+ {
+ sep = 1.0;
+ }
+
+ return 1.0 - sep;
+}
+
+double YansErrorRateModel::SymbolErrorProb256Cck (double e1) const
+{
+ return 1.0 - pow (1.0 - SymbolErrorProb16Cck (e1/2.0), 2.0);
+}
+
+#endif
+
} // namespace ns3
--- a/src/devices/wifi/yans-error-rate-model.h Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/yans-error-rate-model.h Thu May 28 20:10:27 2009 +0200
@@ -21,11 +21,51 @@
#define YANS_ERROR_RATE_MODEL_H
#include <stdint.h>
+#ifdef ENABLE_GSL
+#include <gsl/gsl_math.h>
+#include <gsl/gsl_integration.h>
+#include <gsl/gsl_cdf.h>
+#include <gsl/gsl_sf_bessel.h>
+#endif
#include "wifi-mode.h"
#include "error-rate-model.h"
namespace ns3 {
+#ifdef ENABLE_GSL
+typedef struct FunctionParameterType
+{
+ double beta;
+ double n;
+} FunctionParameters;
+
+double IntegralFunction (double x, void *params);
+#endif
+
+/**
+ * \brief Model the error rate for different modulations.
+ *
+ * A packet of interest (e.g., a packet can potentially be received by the MAC)
+ * is divided into chunks. Each chunk is related to an start/end receiving event.
+ * For each chunk, it calculates the ratio (SINR) between received power of packet
+ * of interest and summation of noise and interfering power of all the other incoming
+ * packets. Then, it will calculate the success rate of the chunk based on
+ * BER of the modulation. The success reception rate of the packet is derived from
+ * the success rate of all chunks.
+ *
+ * The 802.11b modulations:
+ * - 1 Mbps mode is based on DBPSK. BER is from equation 5.2-69 from John G. Proakis
+ * Digitial Communications, 2001 edition
+ * - 2 Mbps model is based on DQPSK. Equation 8 from "Tight bounds and accurate
+ * approximations for dqpsk transmission bit error rate", G. Ferrari and G.E. Corazza
+ * ELECTRONICS LETTERS, 40(20):1284-1285, September 2004
+ * - 5.5 Mbps and 11 Mbps are based on equations (18) and (17) from "Properties and
+ * performance of the ieee 802.11b complementarycode-key signal sets",
+ * Michael B. Pursley and Thomas C. Royster. IEEE TRANSACTIONS ON COMMUNICATIONS,
+ * 57(2):440-449, February 2009.
+ * - More detailed description and validation can be found in
+ * http://www.nsnam.org/~pei/80211b.pdf
+ */
class YansErrorRateModel : public ErrorRateModel
{
public:
@@ -52,6 +92,19 @@
uint32_t phyRate,
uint32_t m, uint32_t dfree,
uint32_t adFree, uint32_t adFreePlusOne) const;
+ double DqpskFunction (double x) const;
+ double Get80211bDsssDbpskSuccessRate (double sinr, uint32_t nbits) const;
+ double Get80211bDsssDqpskSuccessRate (double sinr,uint32_t nbits) const;
+ double Get80211bDsssDqpskCck5_5SuccessRate (double sinr,uint32_t nbits) const;
+ double Get80211bDsssDqpskCck11SuccessRate (double sinr,uint32_t nbits) const;
+#ifdef ENABLE_GSL
+ double SymbolErrorProb16Cck (double e2) const; /// equation (18) in Pursley's paper
+ double SymbolErrorProb256Cck (double e1) const; /// equation (17) in Pursley's paper
+#endif
+
+private:
+ static const double WLAN_SIR_PERFECT = 10.0;
+ static const double WLAN_SIR_IMPOSSIBLE = 0.1;
};
--- a/src/devices/wifi/yans-wifi-phy.cc Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/yans-wifi-phy.cc Thu May 28 20:10:27 2009 +0200
@@ -110,6 +110,7 @@
EnumValue (WIFI_PHY_STANDARD_80211a),
MakeEnumAccessor (&YansWifiPhy::SetStandard),
MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
+ WIFI_PHY_STANDARD_80211b, "802.11b",
WIFI_PHY_STANDARD_holland, "holland"))
.AddAttribute ("State", "The state of the PHY layer",
PointerValue (),
@@ -150,6 +151,9 @@
case WIFI_PHY_STANDARD_80211a:
Configure80211a ();
break;
+ case WIFI_PHY_STANDARD_80211b:
+ Configure80211b ();
+ break;
case WIFI_PHY_STANDARD_holland:
ConfigureHolland ();
break;
@@ -440,6 +444,18 @@
m_modes.push_back (WifiPhy::Get54mba ());
}
+
+void
+YansWifiPhy::Configure80211b (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_interference.Configure80211bParameters ();
+ m_modes.push_back (WifiPhy::Get1mbb ());
+ m_modes.push_back (WifiPhy::Get2mbb ());
+ m_modes.push_back (WifiPhy::Get5_5mbb ());
+ m_modes.push_back (WifiPhy::Get11mbb ());
+}
+
void
YansWifiPhy::ConfigureHolland (void)
{
--- a/src/devices/wifi/yans-wifi-phy.h Thu May 28 20:09:28 2009 +0200
+++ b/src/devices/wifi/yans-wifi-phy.h Thu May 28 20:10:27 2009 +0200
@@ -124,6 +124,7 @@
YansWifiPhy (const YansWifiPhy &o);
virtual void DoDispose (void);
void Configure80211a (void);
+ void Configure80211b (void);
void ConfigureHolland (void);
double GetEdThresholdW (void) const;
double DbmToW (double dbm) const;
--- a/src/wscript Thu May 28 20:09:28 2009 +0200
+++ b/src/wscript Thu May 28 20:10:27 2009 +0200
@@ -53,6 +53,7 @@
conf.sub_config('core')
conf.sub_config('simulator')
conf.sub_config('devices/emu')
+ conf.sub_config('devices/wifi')
conf.sub_config('devices/tap-bridge')
conf.sub_config('contrib')
conf.sub_config('internet-stack')