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
71using namespace ns3;
72
73NS_LOG_COMPONENT_DEFINE ("test-interference-helper");
74
75bool checkResults = false;
78
81{
82public:
84 struct Input
85 {
86 Input ();
88 double xA;
89 double xB;
90 std::string txModeA;
91 std::string txModeB;
96 uint16_t channelA;
97 uint16_t channelB;
98 uint16_t widthA;
99 uint16_t widthB;
105 };
106
112 void Run (struct InterferenceExperiment::Input input);
113
114private:
122 void SendA (void) const;
124 void SendB (void) const;
127 struct Input m_input;
130 mutable uint64_t m_uidA;
131 mutable uint64_t m_uidB;
132};
133
134void
136{
137 WifiMacHeader hdr;
138 hdr.SetType (WIFI_MAC_CTL_ACK); //so that size may not be empty while being as short as possible
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);
147 m_txA->Send (psdu, txVector);
148}
149
150void
152{
153 WifiMacHeader hdr;
154 hdr.SetType (WIFI_MAC_CTL_ACK); //so that size may not be empty while being as short as possible
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);
163 m_txB->Send (psdu, txVector);
164}
165
166void
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
214void
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> ();
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
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
315int 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 {
362 }
363 else if (str_standard == "WIFI_PHY_STANDARD_80211g")
364 {
367 }
368 else if (str_standard == "WIFI_PHY_STANDARD_80211n_2_4GHZ")
369 {
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 {
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
void Run(ObjectFactory &factory, uint32_t pop, uint32_t total, uint32_t runs, Ptr< RandomVariableStream > eventStream, bool calRev)
Perform the runs for a single scheduler type.
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:104
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:600
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1568
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:608
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:883
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:993
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:569
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:504
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:581
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:622
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:839
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:491
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:258
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:206
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1261
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
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.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:661
@ WIFI_MAC_CTL_ACK
cmd
Definition: second.py:43
channel
Definition: third.py:83
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
True if Rx from B is expected to be successful.
bool checkResults
True if results have to be checked.
bool expectRxASuccessfull
True if Rx from A is expected to be successful.