802.11b PHY support
This commit is contained in:
229
examples/wifi-clear-channel-cmu.cc
Normal file
229
examples/wifi-clear-channel-cmu.cc
Normal 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;
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace ns3 {
|
||||
|
||||
enum WifiPhyStandard {
|
||||
WIFI_PHY_STANDARD_80211a,
|
||||
WIFI_PHY_STANDARD_80211b,
|
||||
WIFI_PHY_STANDARD_holland
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
|
||||
@@ -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 = ¶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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user