A Discrete-Event Network Simulator
API
wifi-test-interference-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2015
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  * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
19  */
20 
21 //
22 // This script is used to verify the behavior of InterferenceHelper.
23 //
24 // The scenario consists of two IEEE 802.11 hidden stations and an access point.
25 // The two stations have both a packet to transmit to the access point.
26 //
27 //
28 // (xA,0,0) (0,0,0) (xB,0,0)
29 //
30 // * -----> * <----- *
31 // | | |
32 // STA A AP STA B
33 //
34 //
35 // The program can be configured at run-time by passing command-line arguments.
36 // It enables to configure the delay between the transmission from station A
37 // and the transmission from station B (--delay option). It is also possible to
38 // select the tx power level (--txPowerA and --txPowerB options), the packet size
39 // (--packetSizeA and --packetSizeB options) and the modulation (--txModeA and
40 // --txModeB options) used for the respective transmissions.
41 //
42 // By default, IEEE 802.11a with long preamble type is considered, but those
43 // parameters can be also picked among other IEEE 802.11 flavors and preamble
44 // types available in the simulator (--standard and --preamble options).
45 // Note that the program checks the consistency between the selected standard
46 // the selected preamble type.
47 //
48 // The output of the program displays InterfenceHelper and SpectrumWifiPhy trace
49 // logs associated to the chosen scenario.
50 //
51 
52 #include "ns3/log.h"
53 #include "ns3/node.h"
54 #include "ns3/packet.h"
55 #include "ns3/config.h"
56 #include "ns3/double.h"
57 #include "ns3/simulator.h"
58 #include "ns3/command-line.h"
59 #include "ns3/single-model-spectrum-channel.h"
60 #include "ns3/spectrum-wifi-phy.h"
61 #include "ns3/propagation-loss-model.h"
62 #include "ns3/propagation-delay-model.h"
63 #include "ns3/interference-helper.h"
64 #include "ns3/nist-error-rate-model.h"
65 #include "ns3/constant-position-mobility-model.h"
66 #include "ns3/simple-frame-capture-model.h"
67 #include "ns3/wifi-psdu.h"
68 #include "ns3/wifi-mac-trailer.h"
69 #include "ns3/wifi-net-device.h"
70 
71 using namespace ns3;
72 
73 NS_LOG_COMPONENT_DEFINE ("test-interference-helper");
74 
75 bool checkResults = false;
76 bool expectRxASuccessfull = false;
77 bool expectRxBSuccessfull = false;
78 
81 {
82 public:
84  struct Input
85  {
86  Input ();
88  double xA;
89  double xB;
90  std::string txModeA;
91  std::string txModeB;
92  double txPowerLevelA;
93  double txPowerLevelB;
94  uint32_t packetSizeA;
95  uint32_t packetSizeB;
96  uint16_t channelA;
97  uint16_t channelB;
98  uint16_t widthA;
99  uint16_t widthB;
104  double captureMargin;
105  };
106 
112  void Run (struct InterferenceExperiment::Input input);
113 
114 private:
120  void PacketDropped (Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
122  void SendA (void) const;
124  void SendB (void) const;
127  struct Input m_input;
128  bool m_droppedA;
129  bool m_droppedB;
130  mutable uint64_t m_uidA;
131  mutable uint64_t m_uidB;
132 };
133 
134 void
136 {
137  WifiMacHeader hdr;
138  hdr.SetType (WIFI_MAC_CTL_ACK); //so that size may not be empty while being as short as possible
139  Ptr<Packet> p = Create<Packet> (m_input.packetSizeA - hdr.GetSerializedSize () - WIFI_MAC_FCS_LENGTH);
140  m_uidA = p->GetUid ();
141  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (p, hdr);
142  WifiTxVector txVector;
143  txVector.SetTxPowerLevel (0); //only one TX power level
144  txVector.SetMode (WifiMode (m_input.txModeA));
145  txVector.SetChannelWidth (m_input.widthA);
146  txVector.SetPreambleType (m_input.preamble);
147  m_txA->Send (psdu, txVector);
148 }
149 
150 void
152 {
153  WifiMacHeader hdr;
154  hdr.SetType (WIFI_MAC_CTL_ACK); //so that size may not be empty while being as short as possible
155  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB - hdr.GetSerializedSize () - WIFI_MAC_FCS_LENGTH);
156  m_uidB = p->GetUid ();
157  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (p, hdr);
158  WifiTxVector txVector;
159  txVector.SetTxPowerLevel (0); //only one TX power level
160  txVector.SetMode (WifiMode (m_input.txModeB));
161  txVector.SetChannelWidth (m_input.widthB);
162  txVector.SetPreambleType (m_input.preamble);
163  m_txB->Send (psdu, txVector);
164 }
165 
166 void
168 {
169  if (packet->GetUid () == m_uidA)
170  {
171  m_droppedA = true;
172  }
173  else if (packet->GetUid () == m_uidB)
174  {
175  m_droppedB = true;
176  }
177  else
178  {
179  NS_LOG_ERROR ("Unknown packet!");
180  exit (1);
181  }
182 }
183 
185  : m_droppedA (false),
186  m_droppedB (false),
187  m_uidA (0),
188  m_uidB (0)
189 {
190 }
191 
193  : interval (MicroSeconds (0)),
194  xA (-5),
195  xB (5),
196  txModeA ("OfdmRate54Mbps"),
197  txModeB ("OfdmRate54Mbps"),
198  txPowerLevelA (16.0206),
199  txPowerLevelB (16.0206),
200  packetSizeA (1500),
201  packetSizeB (1500),
202  channelA (36),
203  channelB (36),
204  widthA (20),
205  widthB (20),
206  standard (WIFI_STANDARD_80211a),
207  band (WIFI_PHY_BAND_5GHZ),
208  preamble (WIFI_PREAMBLE_LONG),
209  captureEnabled (false),
210  captureMargin (0)
211 {
212 }
213 
214 void
216 {
217  m_input = input;
218 
219  double range = std::max (std::abs (input.xA), input.xB);
220  Config::SetDefault ("ns3::RangePropagationLossModel::MaxRange", DoubleValue (range));
221 
222  Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
223  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
224  Ptr<RangePropagationLossModel> loss = CreateObject<RangePropagationLossModel> ();
225  channel->AddPropagationLossModel (loss);
226 
227  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
228  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
229  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
230  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
231  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
232  posRx->SetPosition (Vector (0.0, 0.0, 0.0));
233 
234  Ptr<Node> nodeA = CreateObject<Node> ();
235  Ptr<WifiNetDevice> devA = CreateObject<WifiNetDevice> ();
236  m_txA = CreateObject<SpectrumWifiPhy> ();
238  m_txA->SetDevice (devA);
241 
242  Ptr<Node> nodeB = CreateObject<Node> ();
243  Ptr<WifiNetDevice> devB = CreateObject<WifiNetDevice> ();
244  m_txB = CreateObject<SpectrumWifiPhy> ();
246  m_txB->SetDevice (devB);
249 
250  Ptr<Node> nodeRx = CreateObject<Node> ();
251  Ptr<WifiNetDevice> devRx = CreateObject<WifiNetDevice> ();
252  Ptr<SpectrumWifiPhy> rx = CreateObject<SpectrumWifiPhy> ();
253  rx->CreateWifiSpectrumPhyInterface (devRx);
254  rx->SetDevice (devRx);
255 
256  Ptr<InterferenceHelper> interferenceTxA = CreateObject<InterferenceHelper> ();
257  m_txA->SetInterferenceHelper (interferenceTxA);
258  Ptr<ErrorRateModel> errorTxA = CreateObject<NistErrorRateModel> ();
259  m_txA->SetErrorRateModel (errorTxA);
260  Ptr<InterferenceHelper> interferenceTxB = CreateObject<InterferenceHelper> ();
261  m_txB->SetInterferenceHelper (interferenceTxB);
262  Ptr<ErrorRateModel> errorTxB = CreateObject<NistErrorRateModel> ();
263  m_txB->SetErrorRateModel (errorTxB);
264  Ptr<InterferenceHelper> interferenceRx = CreateObject<InterferenceHelper> ();
265  rx->SetInterferenceHelper (interferenceRx);
266  Ptr<ErrorRateModel> errorRx = CreateObject<NistErrorRateModel> ();
267  rx->SetErrorRateModel (errorRx);
270  rx->SetChannel (channel);
271  m_txA->SetMobility (posTxA);
272  m_txB->SetMobility (posTxB);
273  rx->SetMobility (posRx);
274  if (input.captureEnabled)
275  {
276  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
277  frameCaptureModel->SetMargin (input.captureMargin);
278  rx->SetFrameCaptureModel (frameCaptureModel);
279  }
280 
283  rx->ConfigureStandard (input.standard);
284 
285  devA->SetPhy (m_txA);
286  nodeA->AddDevice (devA);
287  devB->SetPhy (m_txB);
288  nodeB->AddDevice (devB);
289  devRx->SetPhy (rx);
290  nodeRx->AddDevice (devRx);
291 
292  m_txA->SetOperatingChannel (WifiPhy::ChannelTuple {input.channelA, 0, (int)(input.band), 0});
293  m_txB->SetOperatingChannel (WifiPhy::ChannelTuple {input.channelB, 0, (int)(input.band), 0});
295  (int)(input.band), 0});
296 
298 
299  Simulator::Schedule (Seconds (0), &InterferenceExperiment::SendA, this);
300  Simulator::Schedule (Seconds (0) + input.interval, &InterferenceExperiment::SendB, this);
301 
302  Simulator::Run ();
303  Simulator::Destroy ();
304  m_txB->Dispose ();
305  m_txA->Dispose ();
306  rx->Dispose ();
307 
309  {
310  NS_LOG_ERROR ("Results are not expected!");
311  exit (1);
312  }
313 }
314 
315 int main (int argc, char *argv[])
316 {
318  std::string str_standard = "WIFI_PHY_STANDARD_80211a";
319  std::string str_preamble = "WIFI_PREAMBLE_LONG";
320  uint64_t delay = 0; //microseconds
321 
322  CommandLine cmd (__FILE__);
323  cmd.AddValue ("delay", "Delay in microseconds between frame transmission from sender A and frame transmission from sender B", delay);
324  cmd.AddValue ("xA", "The position of transmitter A (< 0)", input.xA);
325  cmd.AddValue ("xB", "The position of transmitter B (> 0)", input.xB);
326  cmd.AddValue ("packetSizeA", "Packet size in bytes of transmitter A", input.packetSizeA);
327  cmd.AddValue ("packetSizeB", "Packet size in bytes of transmitter B", input.packetSizeB);
328  cmd.AddValue ("txPowerA", "TX power level of transmitter A", input.txPowerLevelA);
329  cmd.AddValue ("txPowerB", "TX power level of transmitter B", input.txPowerLevelB);
330  cmd.AddValue ("txModeA", "Wifi mode used for payload transmission of sender A", input.txModeA);
331  cmd.AddValue ("txModeB", "Wifi mode used for payload transmission of sender B", input.txModeB);
332  cmd.AddValue ("channelA", "The selected channel number of sender A", input.channelA);
333  cmd.AddValue ("channelB", "The selected channel number of sender B", input.channelB);
334  cmd.AddValue ("widthA", "The selected channel width (MHz) of sender A", input.widthA);
335  cmd.AddValue ("widthB", "The selected channel width (MHz) of sender B", input.widthB);
336  cmd.AddValue ("standard", "IEEE 802.11 flavor", str_standard);
337  cmd.AddValue ("preamble", "Type of preamble", str_preamble);
338  cmd.AddValue ("enableCapture", "Enable/disable physical layer capture", input.captureEnabled);
339  cmd.AddValue ("captureMargin", "Margin used for physical layer capture", input.captureMargin);
340  cmd.AddValue ("checkResults", "Used to check results at the end of the test", checkResults);
341  cmd.AddValue ("expectRxASuccessfull", "Indicate whether packet A is expected to be successfully received", expectRxASuccessfull);
342  cmd.AddValue ("expectRxBSuccessfull", "Indicate whether packet B is expected to be successfully received", expectRxBSuccessfull);
343  cmd.Parse (argc, argv);
344 
345  input.interval = MicroSeconds (delay);
346 
347  if (input.xA >= 0 || input.xB <= 0)
348  {
349  std::cout << "Value of xA must be smaller than 0 and value of xB must be bigger than 0!" << std::endl;
350  return 0;
351  }
352 
353  if (str_standard == "WIFI_PHY_STANDARD_80211a")
354  {
356  input.band = WIFI_PHY_BAND_5GHZ;
357  }
358  else if (str_standard == "WIFI_PHY_STANDARD_80211b")
359  {
361  input.band = WIFI_PHY_BAND_2_4GHZ;
362  }
363  else if (str_standard == "WIFI_PHY_STANDARD_80211g")
364  {
366  input.band = WIFI_PHY_BAND_2_4GHZ;
367  }
368  else if (str_standard == "WIFI_PHY_STANDARD_80211n_2_4GHZ")
369  {
371  input.band = WIFI_PHY_BAND_2_4GHZ;
372  }
373  else if (str_standard == "WIFI_PHY_STANDARD_80211n_5GHZ")
374  {
376  input.band = WIFI_PHY_BAND_5GHZ;
377  }
378  else if (str_standard == "WIFI_PHY_STANDARD_80211ac")
379  {
381  input.band = WIFI_PHY_BAND_5GHZ;
382  }
383  else if (str_standard == "WIFI_PHY_STANDARD_80211ax_2_4GHZ")
384  {
386  input.band = WIFI_PHY_BAND_2_4GHZ;
387  }
388  else if (str_standard == "WIFI_PHY_STANDARD_80211ax_5GHZ")
389  {
391  input.band = WIFI_PHY_BAND_5GHZ;
392  }
393 
394  if (str_preamble == "WIFI_PREAMBLE_LONG" && (input.standard == WIFI_STANDARD_80211a || input.standard == WIFI_STANDARD_80211b || input.standard == WIFI_STANDARD_80211g))
395  {
397  }
398  else if (str_preamble == "WIFI_PREAMBLE_SHORT" && (input.standard == WIFI_STANDARD_80211b || input.standard == WIFI_STANDARD_80211g))
399  {
401  }
402  else if (str_preamble == "WIFI_PREAMBLE_HT_MF" && input.standard == WIFI_STANDARD_80211n)
403  {
405  }
406  else if (str_preamble == "WIFI_PREAMBLE_VHT_SU" && input.standard == WIFI_STANDARD_80211ac)
407  {
409  }
410  else if (str_preamble == "WIFI_PREAMBLE_HE_SU" && input.standard == WIFI_STANDARD_80211ax)
411  {
413  }
414  else
415  {
416  std::cout << "Preamble does not exist or is not compatible with the selected standard!" << std::endl;
417  return 0;
418  }
419 
421  experiment.Run (input);
422 
423  return 0;
424 }
#define max(a, b)
Definition: 80211b.c:43
Ptr< SpectrumWifiPhy > m_txA
transmit A function
void SendA(void) const
Send A function.
bool m_droppedB
flag to indicate whether packet B has been dropped
uint64_t m_uidB
UID to use for packet B.
bool m_droppedA
flag to indicate whether packet A has been dropped
void PacketDropped(Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Function triggered when a packet is dropped.
Ptr< SpectrumWifiPhy > m_txB
transmit B function
uint64_t m_uidA
UID to use for packet A.
void Run(struct InterferenceExperiment::Input input)
Run function.
void SendB(void) const
Send B function.
Parse command-line arguments.
Definition: command-line.h:229
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
void SetPosition(const Vector &position)
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:364
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:390
void SetChannel(const Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
void CreateWifiSpectrumPhyInterface(Ptr< NetDevice > device)
Method to encapsulate the creation of the WifiSpectrumPhyInterface object (used to bind the WifiSpect...
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Implements the IEEE 802.11 MAC header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
uint32_t GetSerializedSize(void) const override
represent a single transmission mode
Definition: wifi-mode.h:48
void SetPhy(const Ptr< WifiPhy > phy)
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:566
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:574
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:835
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:930
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:535
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:470
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:547
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:588
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:833
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:457
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
void experiment(std::string queue_disc_type)
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PREAMBLE_VHT_SU
@ WIFI_PREAMBLE_SHORT
@ WIFI_PREAMBLE_HT_MF
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
@ WIFI_MAC_CTL_ACK
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
cmd
Definition: second.py:35
channel
Definition: third.py:92
double txPowerLevelA
transmit power level A
double txPowerLevelB
transmit power level B
bool captureEnabled
whether physical layer capture is enabled
double captureMargin
margin used for physical layer capture
bool expectRxBSuccessfull
bool expectRxASuccessfull