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/nist-error-rate-model.h"
64 #include "ns3/constant-position-mobility-model.h"
65 #include "ns3/simple-frame-capture-model.h"
66 #include "ns3/wifi-psdu.h"
67 #include "ns3/wifi-mac-trailer.h"
68 #include "ns3/wifi-net-device.h"
69 
70 using namespace ns3;
71 
72 NS_LOG_COMPONENT_DEFINE ("test-interference-helper");
73 
74 bool checkResults = false;
75 bool expectRxASuccessfull = false;
76 bool expectRxBSuccessfull = false;
77 
80 {
81 public:
83  struct Input
84  {
85  Input ();
87  double xA;
88  double xB;
89  std::string txModeA;
90  std::string txModeB;
91  double txPowerLevelA;
92  double txPowerLevelB;
93  uint32_t packetSizeA;
94  uint32_t packetSizeB;
95  uint16_t channelA;
96  uint16_t channelB;
97  uint16_t widthA;
98  uint16_t widthB;
102  double captureMargin;
103  };
104 
110  void Run (struct InterferenceExperiment::Input input);
111 
112 private:
118  void PacketDropped (Ptr<const Packet> packet, WifiPhyRxfailureReason reason);
120  void SendA (void) const;
122  void SendB (void) const;
125  struct Input m_input;
126  bool m_droppedA;
127  bool m_droppedB;
128  mutable uint64_t m_uidA;
129  mutable uint64_t m_uidB;
130 };
131 
132 void
134 {
135  WifiMacHeader hdr;
136  hdr.SetType (WIFI_MAC_CTL_ACK); //so that size may not be empty while being as short as possible
137  Ptr<Packet> p = Create<Packet> (m_input.packetSizeA - hdr.GetSerializedSize () - WIFI_MAC_FCS_LENGTH);
138  m_uidA = p->GetUid ();
139  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (p, hdr);
140  WifiTxVector txVector;
141  txVector.SetTxPowerLevel (0); //only one TX power level
142  txVector.SetMode (WifiMode (m_input.txModeA));
143  txVector.SetChannelWidth (m_input.widthA);
144  txVector.SetPreambleType (m_input.preamble);
145  m_txA->Send (psdu, txVector);
146 }
147 
148 void
150 {
151  WifiMacHeader hdr;
152  hdr.SetType (WIFI_MAC_CTL_ACK); //so that size may not be empty while being as short as possible
153  Ptr<Packet> p = Create<Packet> (m_input.packetSizeB - hdr.GetSerializedSize () - WIFI_MAC_FCS_LENGTH);
154  m_uidB = p->GetUid ();
155  Ptr<WifiPsdu> psdu = Create<WifiPsdu> (p, hdr);
156  WifiTxVector txVector;
157  txVector.SetTxPowerLevel (0); //only one TX power level
158  txVector.SetMode (WifiMode (m_input.txModeB));
159  txVector.SetChannelWidth (m_input.widthB);
160  txVector.SetPreambleType (m_input.preamble);
161  m_txB->Send (psdu, txVector);
162 }
163 
164 void
166 {
167  if (packet->GetUid () == m_uidA)
168  {
169  m_droppedA = true;
170  }
171  else if (packet->GetUid () == m_uidB)
172  {
173  m_droppedB = true;
174  }
175  else
176  {
177  NS_LOG_ERROR ("Unknown packet!");
178  exit (1);
179  }
180 }
181 
183  : m_droppedA (false),
184  m_droppedB (false),
185  m_uidA (0),
186  m_uidB (0)
187 {
188 }
189 
191  : interval (MicroSeconds (0)),
192  xA (-5),
193  xB (5),
194  txModeA ("OfdmRate54Mbps"),
195  txModeB ("OfdmRate54Mbps"),
196  txPowerLevelA (16.0206),
197  txPowerLevelB (16.0206),
198  packetSizeA (1500),
199  packetSizeB (1500),
200  channelA (36),
201  channelB (36),
202  widthA (20),
203  widthB (20),
204  standard (WIFI_PHY_STANDARD_80211a),
205  preamble (WIFI_PREAMBLE_LONG),
206  captureEnabled (false),
207  captureMargin (0)
208 {
209 }
210 
211 void
213 {
214  m_input = input;
215 
216  double range = std::max (std::abs (input.xA), input.xB);
217  Config::SetDefault ("ns3::RangePropagationLossModel::MaxRange", DoubleValue (range));
218 
219  Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel> ();
220  channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
221  Ptr<RangePropagationLossModel> loss = CreateObject<RangePropagationLossModel> ();
222  channel->AddPropagationLossModel (loss);
223 
224  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel> ();
225  posTxA->SetPosition (Vector (input.xA, 0.0, 0.0));
226  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel> ();
227  posTxB->SetPosition (Vector (input.xB, 0.0, 0.0));
228  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel> ();
229  posRx->SetPosition (Vector (0.0, 0.0, 0.0));
230 
231  Ptr<Node> nodeA = CreateObject<Node> ();
232  Ptr<WifiNetDevice> devA = CreateObject<WifiNetDevice> ();
233  m_txA = CreateObject<SpectrumWifiPhy> ();
235  m_txA->SetDevice (devA);
238 
239  Ptr<Node> nodeB = CreateObject<Node> ();
240  Ptr<WifiNetDevice> devB = CreateObject<WifiNetDevice> ();
241  m_txB = CreateObject<SpectrumWifiPhy> ();
243  m_txB->SetDevice (devB);
246 
247  Ptr<Node> nodeRx = CreateObject<Node> ();
248  Ptr<WifiNetDevice> devRx = CreateObject<WifiNetDevice> ();
249  Ptr<SpectrumWifiPhy> rx = CreateObject<SpectrumWifiPhy> ();
250  rx->CreateWifiSpectrumPhyInterface (devRx);
251  rx->SetDevice (devRx);
252 
253  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
254  m_txA->SetErrorRateModel (error);
255  m_txB->SetErrorRateModel (error);
256  rx->SetErrorRateModel (error);
259  rx->SetChannel (channel);
260  m_txA->SetMobility (posTxA);
261  m_txB->SetMobility (posTxB);
262  rx->SetMobility (posRx);
263  if (input.captureEnabled)
264  {
265  Ptr<SimpleFrameCaptureModel> frameCaptureModel = CreateObject<SimpleFrameCaptureModel> ();
266  frameCaptureModel->SetMargin (input.captureMargin);
267  rx->SetFrameCaptureModel (frameCaptureModel);
268  }
269 
272  rx->ConfigureStandard (input.standard);
273 
274  devA->SetPhy (m_txA);
275  nodeA->AddDevice (devA);
276  devB->SetPhy (m_txB);
277  nodeB->AddDevice (devB);
278  devRx->SetPhy (rx);
279  nodeRx->AddDevice (devRx);
280 
283  rx->SetChannelNumber (std::max (input.channelA, input.channelB));
284 
285  rx->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&InterferenceExperiment::PacketDropped, this));
286 
287  Simulator::Schedule (Seconds (0), &InterferenceExperiment::SendA, this);
288  Simulator::Schedule (Seconds (0) + input.interval, &InterferenceExperiment::SendB, this);
289 
290  Simulator::Run ();
291  Simulator::Destroy ();
292  m_txB->Dispose ();
293  m_txA->Dispose ();
294  rx->Dispose ();
295 
297  {
298  NS_LOG_ERROR ("Results are not expected!");
299  exit (1);
300  }
301 }
302 
303 int main (int argc, char *argv[])
304 {
306  std::string str_standard = "WIFI_PHY_STANDARD_80211a";
307  std::string str_preamble = "WIFI_PREAMBLE_LONG";
308  uint64_t delay = 0; //microseconds
309 
310  CommandLine cmd (__FILE__);
311  cmd.AddValue ("delay", "Delay in microseconds between frame transmission from sender A and frame transmission from sender B", delay);
312  cmd.AddValue ("xA", "The position of transmitter A (< 0)", input.xA);
313  cmd.AddValue ("xB", "The position of transmitter B (> 0)", input.xB);
314  cmd.AddValue ("packetSizeA", "Packet size in bytes of transmitter A", input.packetSizeA);
315  cmd.AddValue ("packetSizeB", "Packet size in bytes of transmitter B", input.packetSizeB);
316  cmd.AddValue ("txPowerA", "TX power level of transmitter A", input.txPowerLevelA);
317  cmd.AddValue ("txPowerB", "TX power level of transmitter B", input.txPowerLevelB);
318  cmd.AddValue ("txModeA", "Wifi mode used for payload transmission of sender A", input.txModeA);
319  cmd.AddValue ("txModeB", "Wifi mode used for payload transmission of sender B", input.txModeB);
320  cmd.AddValue ("channelA", "The selected channel number of sender A", input.channelA);
321  cmd.AddValue ("channelB", "The selected channel number of sender B", input.channelB);
322  cmd.AddValue ("widthA", "The selected channel width (MHz) of sender A", input.widthA);
323  cmd.AddValue ("widthB", "The selected channel width (MHz) of sender B", input.widthB);
324  cmd.AddValue ("standard", "IEEE 802.11 flavor", str_standard);
325  cmd.AddValue ("preamble", "Type of preamble", str_preamble);
326  cmd.AddValue ("enableCapture", "Enable/disable physical layer capture", input.captureEnabled);
327  cmd.AddValue ("captureMargin", "Margin used for physical layer capture", input.captureMargin);
328  cmd.AddValue ("checkResults", "Used to check results at the end of the test", checkResults);
329  cmd.AddValue ("expectRxASuccessfull", "Indicate whether packet A is expected to be successfully received", expectRxASuccessfull);
330  cmd.AddValue ("expectRxBSuccessfull", "Indicate whether packet B is expected to be successfully received", expectRxBSuccessfull);
331  cmd.Parse (argc, argv);
332 
333  input.interval = MicroSeconds (delay);
334 
335  if (input.xA >= 0 || input.xB <= 0)
336  {
337  std::cout << "Value of xA must be smaller than 0 and value of xB must be bigger than 0!" << std::endl;
338  return 0;
339  }
340 
341  if (str_standard == "WIFI_PHY_STANDARD_80211a")
342  {
344  }
345  else if (str_standard == "WIFI_PHY_STANDARD_80211b")
346  {
348  }
349  else if (str_standard == "WIFI_PHY_STANDARD_80211g")
350  {
352  }
353  else if (str_standard == "WIFI_PHY_STANDARD_80211n_2_4GHZ")
354  {
356  }
357  else if (str_standard == "WIFI_PHY_STANDARD_80211n_5GHZ")
358  {
360  }
361  else if (str_standard == "WIFI_PHY_STANDARD_80211ac")
362  {
364  }
365  else if (str_standard == "WIFI_PHY_STANDARD_80211ax_2_4GHZ")
366  {
368  }
369  else if (str_standard == "WIFI_PHY_STANDARD_80211ax_5GHZ")
370  {
372  }
373 
374  if (str_preamble == "WIFI_PREAMBLE_LONG" && (input.standard == WIFI_PHY_STANDARD_80211a || input.standard == WIFI_PHY_STANDARD_80211b || input.standard == WIFI_PHY_STANDARD_80211g))
375  {
377  }
378  else if (str_preamble == "WIFI_PREAMBLE_SHORT" && (input.standard == WIFI_PHY_STANDARD_80211b || input.standard == WIFI_PHY_STANDARD_80211g))
379  {
381  }
382  else if (str_preamble == "WIFI_PREAMBLE_HT_MF" && (input.standard == WIFI_PHY_STANDARD_80211n_2_4GHZ || input.standard == WIFI_PHY_STANDARD_80211n_5GHZ))
383  {
385  }
386  else if (str_preamble == "WIFI_PREAMBLE_HT_GF" && (input.standard == WIFI_PHY_STANDARD_80211n_2_4GHZ || input.standard == WIFI_PHY_STANDARD_80211n_5GHZ))
387  {
389  }
390  else if (str_preamble == "WIFI_PREAMBLE_VHT_SU" && input.standard == WIFI_PHY_STANDARD_80211ac)
391  {
393  }
394  else if (str_preamble == "WIFI_PREAMBLE_HE_SU" && (input.standard == WIFI_PHY_STANDARD_80211ax_2_4GHZ || input.standard == WIFI_PHY_STANDARD_80211ax_5GHZ))
395  {
397  }
398  else
399  {
400  std::cout << "Preamble does not exist or is not compatible with the selected standard!" << std::endl;
401  return 0;
402  }
403 
405  experiment.Run (input);
406 
407  return 0;
408 }
ERP-OFDM PHY (Clause 19, Section 19.5)
void Dispose(void)
Dispose of this Object.
Definition: object.cc:214
double txPowerLevelB
transmit power level B
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
void SendB(void) const
Send B function.
HT PHY for the 5 GHz band (clause 20)
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool captureEnabled
whether physical layer capture is enabled
bool expectRxBSuccessfull
bool m_droppedB
flag to indicate whether packet B has been dropped
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
HE PHY for the 2.4 GHz band (clause 26)
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:752
cmd
Definition: second.py:35
HT PHY for the 2.4 GHz band (clause 20)
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
virtual void SetChannelNumber(uint8_t id)
Set channel number.
channel
Definition: third.py:92
bool m_droppedA
flag to indicate whether packet A has been dropped
void SetDevice(const Ptr< NetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:728
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:32
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
double captureMargin
margin used for physical layer capture
HE PHY for the 5 GHz band (clause 26)
Ptr< SpectrumWifiPhy > m_txB
transmit B function
#define max(a, b)
Definition: 80211b.c:43
void PacketDropped(Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Function triggered when a packet is dropped.
virtual void ConfigureStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:569
double txPowerLevelA
transmit power level A
Parse command-line arguments.
Definition: command-line.h:221
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:771
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void Run(struct InterferenceExperiment::Input input)
Run function.
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
bool expectRxASuccessfull
void SetPosition(const Vector &position)
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void experiment(std::string queue_disc_type)
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:556
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
Definition: wifi-phy.h:53
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
uint32_t GetSerializedSize(void) const
Ptr< SpectrumWifiPhy > m_txA
transmit A function
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1078
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
void SetMargin(double margin)
Sets the frame capture margin (dB).
void SetChannel(const Ptr< SpectrumChannel > channel)
Set the SpectrumChannel this SpectrumWifiPhy is to be connected to.
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
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:1642
Implements the IEEE 802.11 MAC header.
void CreateWifiSpectrumPhyInterface(Ptr< NetDevice > device)
Method to encapsulate the creation of the WifiSpectrumPhyInterface object (used to bind the WifiSpect...
void SendA(void) const
Send A function.