802.11b PHY support

This commit is contained in:
Gary Pei
2009-05-28 20:10:27 +02:00
parent a5f5038994
commit 7b6bf39786
15 changed files with 627 additions and 9 deletions

View File

@@ -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;
}

View File

@@ -116,6 +116,10 @@ def build(bld):
['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'

View File

@@ -123,7 +123,7 @@ InterferenceHelper::NiChange::operator < (InterferenceHelper::NiChange const &o)
****************************************************************/
InterferenceHelper::InterferenceHelper ()
: m_80211a (false),
: m_80211_standard (WIFI_PHY_STANDARD_80211a),
m_errorRateModel (0)
{}
InterferenceHelper::~InterferenceHelper ()
@@ -227,12 +227,25 @@ InterferenceHelper::GetEnergyDuration (double energyW)
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 @@ void
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 @@ InterferenceHelper::Configure80211aParameters (void)
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)
{

View File

@@ -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 @@ public:
~InterferenceHelper ();
void Configure80211aParameters (void);
void Configure80211bParameters (void);
void SetNoiseFigure (double value);
void SetErrorRateModel (Ptr<ErrorRateModel> rate);
@@ -120,7 +122,7 @@ private:
Time m_maxPacketDuration;
double m_noiseFigure; /**< noise figure (linear) */
Events m_events;
bool m_80211a;
enum WifiPhyStandard m_80211_standard;
Ptr<ErrorRateModel> m_errorRateModel;
};

View File

@@ -165,7 +165,44 @@ WifiModeFactory::CreateQam (std::string uniqueName,
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)
{

View File

@@ -41,6 +41,8 @@ class WifiMode
public:
enum ModulationType {
BPSK,
DBPSK,
DQPSK,
QAM
};
@@ -170,6 +172,40 @@ public:
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);

View File

@@ -24,6 +24,7 @@ namespace ns3 {
enum WifiPhyStandard {
WIFI_PHY_STANDARD_80211a,
WIFI_PHY_STANDARD_80211b,
WIFI_PHY_STANDARD_holland
};

View File

@@ -199,6 +199,43 @@ WifiPhy::NotifyPromiscSniff (Ptr<const Packet> packet)
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 @@ public:
ns3::WifiPhy::Get36mba ();
ns3::WifiPhy::Get48mba ();
ns3::WifiPhy::Get54mba ();
ns3::WifiPhy::Get1mbb ();
ns3::WifiPhy::Get2mbb ();
ns3::WifiPhy::Get5_5mbb ();
ns3::WifiPhy::Get11mbb ();
}
} g_constructor;
}

View File

@@ -252,6 +252,11 @@ public:
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

View File

@@ -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 @@ def build(bld):
'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'

View File

@@ -263,7 +263,159 @@ YansErrorRateModel::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbi
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 = &params;
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

View File

@@ -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 @@ private:
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;
};

View File

@@ -110,6 +110,7 @@ YansWifiPhy::GetTypeId (void)
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 @@ YansWifiPhy::SetStandard (enum WifiPhyStandard standard)
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 @@ YansWifiPhy::Configure80211a (void)
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)
{

View File

@@ -124,6 +124,7 @@ private:
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;

View File

@@ -53,6 +53,7 @@ def configure(conf):
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')