A Discrete-Event Network Simulator
API
wifi-interference-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #include <iostream>
20 #include <fstream>
21 #include <vector>
22 #include <string>
23 
24 #include "ns3/log.h"
25 #include "ns3/callback.h"
26 #include "ns3/abort.h"
27 #include "ns3/test.h"
28 #include "ns3/pcap-file.h"
29 #include "ns3/config.h"
30 #include "ns3/string.h"
31 #include "ns3/uinteger.h"
32 #include "ns3/double.h"
33 #include "ns3/data-rate.h"
34 #include "ns3/inet-socket-address.h"
35 #include "ns3/internet-stack-helper.h"
36 #include "ns3/ipv4-address-helper.h"
37 #include "ns3/tcp-socket-factory.h"
38 #include "ns3/yans-wifi-helper.h"
39 #include "ns3/propagation-loss-model.h"
40 #include "ns3/propagation-delay-model.h"
41 #include "ns3/yans-wifi-channel.h"
42 #include "ns3/yans-wifi-phy.h"
43 #include "ns3/wifi-net-device.h"
44 #include "ns3/mobility-helper.h"
45 #include "ns3/constant-position-mobility-model.h"
46 #include "ns3/nqos-wifi-mac-helper.h"
47 #include "ns3/simulator.h"
48 
49 using namespace ns3;
50 
51 NS_LOG_COMPONENT_DEFINE ("WifiInterferenceTestSuite");
52 
54 {
55 public:
57  virtual ~WifiInterferenceTestCase ();
58 
59 private:
60  virtual void DoRun (void);
61  void ReceivePacket (Ptr<Socket> socket);
62  static void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval);
63  void PrintEndSync (std::string context, uint32_t dataRate, double snr, double per);
64  double WifiSimpleInterference (std::string phyMode, double Prss, double Irss, double delta, uint32_t PpacketSize,
65  uint32_t IpacketSize, bool verbose, InternetStackHelper internet, WifiPhyStandard wifiStandard);
66  double m_PER;
67  double m_SNR;
68  uint32_t m_DataRate;
69 };
70 
71 // Add some help text to this case to describe what it is intended to test
73  : TestCase ("Test interference calculation when interfering frame exactly overlaps intended frame")
74 {
75 }
76 
78 {
79 }
80 
81 static inline std::string
83 {
84  Address addr;
85  socket->GetSockName (addr);
86  InetSocketAddress iaddr = InetSocketAddress::ConvertFrom (addr);
87 
88  std::ostringstream oss;
89  oss << "Received one packet! Socket: " << iaddr.GetIpv4 () << " port: " << iaddr.GetPort ();
90 
91  return oss.str ();
92 }
93 
94 void
96 {
98 }
99 
100 void
101 WifiInterferenceTestCase::GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval)
102 {
103  if (pktCount > 0)
104  {
105  socket->Send (Create<Packet> (pktSize));
106  Simulator::Schedule (pktInterval, &WifiInterferenceTestCase::GenerateTraffic, socket, pktSize, pktCount-1, pktInterval);
107  }
108  else
109  {
110  socket->Close ();
111  }
112 }
113 
114 void
115 WifiInterferenceTestCase::PrintEndSync (std::string context, uint32_t dataRate, double snr, double per)
116 {
117  NS_LOG_UNCOND ("EndSync: Received frame with dataRate=" << dataRate << ", SNR=" << snr << ", PER =" << per);
118  m_PER = per;
119  m_SNR = snr;
120  m_DataRate = dataRate;
121 }
122 
123 double
124 WifiInterferenceTestCase::WifiSimpleInterference (std::string phyMode,double Prss, double Irss, double delta, uint32_t PpacketSize, uint32_t IpacketSize, bool verbose, InternetStackHelper internet, WifiPhyStandard wifiStandard)
125 {
126 
127  uint32_t numPackets = 1;
128  double interval = 1.0; // seconds
129  double startTime = 10.0; // seconds
130  double distanceToRx = 100.0; // meters
131 
132  double offset = 91; // This is a magic number used to set the
133  // transmit power, based on other configuration
134 
135  m_PER = 0;
136  m_SNR = 0;
137  m_DataRate = 0;
138 
139  // Convert to time object
140  Time interPacketInterval = Seconds (interval);
141 
142  // disable fragmentation for frames below 2200 bytes
143  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
144  // turn off RTS/CTS for frames below 2200 bytes
145  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
146  // Fix non-unicast data rate to be the same as that of unicast
147  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
148  StringValue (phyMode));
149 
150  NodeContainer c;
151  c.Create (3);
152 
153  // The below set of helpers will help us to put together the wifi NICs we want
155  wifi.SetStandard (wifiStandard);
156 
157  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
158  // This is one parameter that matters when using FixedRssLossModel
159  // set it to zero; otherwise, gain will be added
160  wifiPhy.Set ("RxGain", DoubleValue (0) );
161  wifiPhy.Set ("CcaMode1Threshold", DoubleValue (0.0) );
162 
163  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
164  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
165 
166  YansWifiChannelHelper wifiChannel;
167  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
168  wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel");
169  wifiPhy.SetChannel (wifiChannel.Create ());
170 
171  // Add a non-QoS upper mac, and disable rate control
172  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
173  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
174  "DataMode",StringValue (phyMode),
175  "ControlMode",StringValue (phyMode));
176  // Set it to adhoc mode
177  wifiMac.SetType ("ns3::AdhocWifiMac");
178  NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c.Get (0));
179  // This will disable these sending devices from detecting a signal
180  // so that they do not backoff
181  wifiPhy.Set ("EnergyDetectionThreshold", DoubleValue (0.0) );
182  wifiPhy.Set ("TxGain", DoubleValue (offset + Prss) );
183  devices.Add (wifi.Install (wifiPhy, wifiMac, c.Get (1)));
184  wifiPhy.Set ("TxGain", DoubleValue (offset + Irss) );
185  devices.Add (wifi.Install (wifiPhy, wifiMac, c.Get (2)));
186 
187  // Note that with FixedRssLossModel, the positions below are not
188  // used for received signal strength.
190  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
191  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
192  positionAlloc->Add (Vector (distanceToRx, 0.0, 0.0));
193  positionAlloc->Add (Vector (-1*distanceToRx, 0.0, 0.0));
194  mobility.SetPositionAllocator (positionAlloc);
195  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
196  mobility.Install (c);
197 
198  // InternetStackHelper internet;
199  internet.Install (c);
200 
201  Ipv4AddressHelper ipv4;
202  NS_LOG_INFO ("Assign IP Addresses.");
203  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
204  Ipv4InterfaceContainer i = ipv4.Assign (devices);
205 
206  TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
207  Ptr<Socket> recvSink = Socket::CreateSocket (c.Get (0), tid);
208  InetSocketAddress local = InetSocketAddress (Ipv4Address ("10.1.1.1"), 80);
209  recvSink->Bind (local);
211 
212  Ptr<Socket> source = Socket::CreateSocket (c.Get (1), tid);
213  InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), 80);
214  source->Connect (remote);
215 
216  // Interferer will send to a different port; we will not see a
217  // "Received packet" message
218  Ptr<Socket> interferer = Socket::CreateSocket (c.Get (2), tid);
219  InetSocketAddress interferingAddr = InetSocketAddress (Ipv4Address ("255.255.255.255"), 49000);
220  interferer->Connect (interferingAddr);
221 
222  Config::Connect ("/NodeList/0/DeviceList/0/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/EndSync", MakeCallback (&WifiInterferenceTestCase::PrintEndSync, this));
223  // Tracing
224 // wifiPhy.EnablePcap ("wifi-simple-interference", devices.Get (0));
225 
226  Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
227  Seconds (startTime), &GenerateTraffic,
228  source, PpacketSize, numPackets, interPacketInterval);
229 
230  Simulator::ScheduleWithContext (interferer->GetNode ()->GetId (),
231  Seconds (startTime + delta/1000000.0), &GenerateTraffic,
232  interferer, IpacketSize, numPackets, interPacketInterval);
233 
234  Simulator::Run ();
235  Simulator::Destroy ();
236 
237  return m_PER;
238 }
239 
240 void
242 {
243 
244  std::string phyMode ("DsssRate1Mbps");
246  double Prss = -90; // -dBm
247  double Irss = -90; // -dBm
248  double delta = 0; // microseconds
249  uint32_t PpacketSize = 1000; // bytes
250  uint32_t IpacketSize = 1000; // bytes
251  bool verbose = false;
252  double PER, PER1, PER2;
253  InternetStackHelper internet;
254 
255  // Compute the packet error rate (PER) when delta=0 microseconds. This
256  // means that the interferer arrives at exactly the same time as the
257  // intended packet
258  PER = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
259 
260  // Now rerun this test case and compute the PER when the delta time between
261  // arrival of the intended frame and interferer is 1 microsecond.
262  delta = 1;
263  PER1 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
264 
265  // Now rerun this test case and compute the PER when the delta time between
266  // arrival of the intended frame and interferer is 2 microseconds.
267  delta = 2;
268  PER2 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
269 
270  double PERDiff1 = PER - PER1;
271 
272  double PERDiff2 = PER1 - PER2;
273 
274  NS_TEST_ASSERT_MSG_EQ (PERDiff1, PERDiff2,
275  "The PER difference due to 1 microsecond difference in arrival shouldn't depend on absolute arrival");
276  //Now rerun for 11n
277  wifiStandard=WIFI_PHY_STANDARD_80211n_2_4GHZ;
278  // Compute the packet error rate (PER) when delta=0 microseconds. This
279  // means that the interferer arrives at exactly the same time as the
280  // intended packet
281  PER = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
282 
283  // Now rerun this test case and compute the PER when the delta time between
284  // arrival of the intended frame and interferer is 1 microsecond.
285  delta = 1;
286  PER1 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
287 
288  // Now rerun this test case and compute the PER when the delta time between
289  // arrival of the intended frame and interferer is 2 microseconds.
290  delta = 2;
291  PER2 = WifiSimpleInterference (phyMode,Prss,Irss,delta,PpacketSize,IpacketSize,verbose,internet,wifiStandard);
292 
293  PERDiff1 = PER - PER1;
294 
295  PERDiff2 = PER1 - PER2;
296 
297  NS_TEST_ASSERT_MSG_EQ (PERDiff1, PERDiff2,
298  "The PER difference due to 1 microsecond difference in arrival shouldn't depend on absolute arrival");
299 
300 }
301 
303 {
304 public:
306 };
307 
309  : TestSuite ("ns3-wifi-interference", UNIT)
310 {
311  AddTestCase (new WifiInterferenceTestCase, TestCase::QUICK);
312 }
313 
315 
void AddPropagationLoss(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
virtual void DoRun(void)
Implementation to actually run this TestCase.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
an Inet address class
Ipv4Address GetIpv4(void) const
tuple devices
Definition: first.py:32
holds a vector of std::pair of Ptr and interface index.
Ptr< YansWifiChannel > Create(void) const
static void GenerateTraffic(Ptr< Socket > socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval)
void SetRemoteStationManager(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Definition: wifi-helper.cc:74
Hold variables of type string.
Definition: string.h:41
Make it easy to create and manage PHY objects for the yans model.
double WifiSimpleInterference(std::string phyMode, double Prss, double Irss, double delta, uint32_t PpacketSize, uint32_t IpacketSize, bool verbose, InternetStackHelper internet, WifiPhyStandard wifiStandard)
A suite of tests to run.
Definition: test.h:1333
virtual void SetType(std::string type, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
static void GenerateTraffic(Ptr< Socket > socket, uint32_t pktSize, Ptr< Node > n, uint32_t pktCount, Time pktInterval)
void ReceivePacket(Ptr< Socket > socket)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual int GetSockName(Address &address) const =0
Get socket address.
void SetPcapDataLinkType(enum SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
void Set(std::string name, const AttributeValue &v)
HT OFDM PHY for the 2.4 GHz band (clause 20)
encapsulates test code
Definition: test.h:1147
helps to create WifiNetDevice objects
Definition: wifi-helper.h:96
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer c) const
Definition: wifi-helper.cc:103
a polymophic address class
Definition: address.h:90
void SetChannel(Ptr< YansWifiChannel > channel)
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
static std::string PrintReceivedPacket(Ptr< Socket > socket)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
tuple mobility
Definition: third.py:101
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:297
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
static WifiInterferenceTestSuite wifiInterferenceTestSuite
double startTime
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:161
holds a vector of ns3::NetDevice pointers
virtual void SetStandard(enum WifiPhyStandard standard)
Definition: wifi-helper.cc:97
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1480
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
create non QoS-enabled MAC layers for a ns3::WifiNetDevice.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:835
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionaly.
manage and create wifi channel objects for the yans model.
Helper class used to assign positions and mobility models to nodes.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
uint32_t GetId(void) const
Definition: node.cc:107
virtual Ptr< Node > GetNode(void) const =0
Return the node this socket is associated with.
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:774
void Add(Vector v)
Add a position to the list of positions.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
uint16_t GetPort(void) const
tuple wifi
Definition: third.py:89
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetPropagationDelay(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
virtual int Close(void)=0
Close a socket.
void ReceivePacket(Ptr< Socket > socket)
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
a unique identifier for an interface.
Definition: type-id.h:58
void PrintEndSync(std::string context, uint32_t dataRate, double snr, double per)
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
bool verbose