A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-trans-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Orange Labs
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Rediet <getachew.redieteab@orange.com>
7 */
8
9#include "ns3/command-line.h"
10#include "ns3/gnuplot.h"
11#include "ns3/mobility-helper.h"
12#include "ns3/spectrum-analyzer-helper.h"
13#include "ns3/spectrum-channel.h"
14#include "ns3/spectrum-helper.h"
15#include "ns3/spectrum-wifi-helper.h"
16#include "ns3/ssid.h"
17#include "ns3/string.h"
18
19using namespace ns3;
20
21/**
22 * This example (inspired from tv-trans-example) enables to generate the transmitted spectra of
23 * Wi-Fi stations, so as to model transmit mask imperfections of OFDM-based Wi-Fi standards.
24 * Only one data packet is sent from access point to station (once association has been performed)
25 * so as to reduce execution time.
26 *
27 * A spectrum analyzer is used to measure the transmitted spectra from Wi-Fi stations.
28 * The file "spectrum-analyzer-wifi-[standard]-[bandwidth]MHz-sim-2-0.tr" contains its
29 * output post simulation and use it to plot transmitted spectra with Gnuplot.
30 *
31 * The wifi-trans-example.sh script runs this example for all combinations, plots transmitted
32 * spectra, and puts resulting png images in wifi-trans-results folder.
33 */
34
35void
36SendPacket(Ptr<NetDevice> sourceDevice, Address& destination)
37{
38 Ptr<Packet> pkt = Create<Packet>(100); // dummy bytes of data
39 sourceDevice->Send(pkt, destination, 0);
40}
41
42int
43main(int argc, char** argv)
44{
45 std::string standardStr = "11a";
46 MHz_u bw = 20;
47 dBm_u pow = 23;
48 bool verbose = false;
49 CommandLine cmd(__FILE__);
50 cmd.AddValue("standard",
51 "OFDM-based Wi-Fi standard [11a, 11p_10MHZ, 11p_5MHZ, 11n_2_4GHZ, 11n_5GHZ, 11ac, "
52 "11ax_2_4GHZ, 11ax_5GHZ]",
53 standardStr);
54 cmd.AddValue("bw", "Bandwidth (consistent with standard, in MHz)", bw);
55 cmd.AddValue("txPower", "Transmit power (dBm)", pow);
56 cmd.AddValue("verbose",
57 "Display log messages for WifiSpectrumValueHelper and SpectrumWifiPhy",
58 verbose);
59 cmd.Parse(argc, argv);
60
62 Ssid ssid;
63 std::string dataRate;
64 MHz_u freq;
65 Time dataStartTime =
66 MicroSeconds(800); // leaving enough time for beacon and association procedure
67 Time dataDuration =
68 MicroSeconds(300); // leaving enough time for data transfer (+ acknowledgment)
69 WifiStandard standard{WifiStandard::WIFI_STANDARD_UNSPECIFIED};
71 std::string channelBand;
72 if (standardStr == "11a")
73 {
74 standard = WIFI_STANDARD_80211a;
75 phyBand = WIFI_PHY_BAND_5GHZ;
76 channelBand = "BAND_5GHZ";
77 ssid = Ssid("ns380211a");
78 dataRate = "OfdmRate6Mbps";
79 freq = 5180;
80 if (bw != 20)
81 {
82 std::cout << "Bandwidth is not compatible with standard" << std::endl;
83 return 1;
84 }
85 }
86 else if (standardStr == "11p_10MHZ")
87 {
88 standard = WIFI_STANDARD_80211p;
89 phyBand = WIFI_PHY_BAND_5GHZ;
90 channelBand = "BAND_5GHZ";
91 ssid = Ssid("ns380211p_10MHZ");
92 dataRate = "OfdmRate3MbpsBW10MHz";
93 freq = 5860;
94 dataStartTime = MicroSeconds(1400);
95 dataDuration = MicroSeconds(600);
96 if (bw != 10)
97 {
98 std::cout << "Bandwidth is not compatible with standard" << std::endl;
99 return 1;
100 }
101 }
102 else if (standardStr == "11p_5MHZ")
103 {
104 standard = WIFI_STANDARD_80211p;
105 phyBand = WIFI_PHY_BAND_5GHZ;
106 channelBand = "BAND_5GHZ";
107 ssid = Ssid("ns380211p_5MHZ");
108 dataRate = "OfdmRate1_5MbpsBW5MHz";
109 freq = 5860;
110 dataStartTime = MicroSeconds(2500);
111 dataDuration = MicroSeconds(1200);
112 if (bw != 5)
113 {
114 std::cout << "Bandwidth is not compatible with standard" << std::endl;
115 return 1;
116 }
117 }
118 else if (standardStr == "11n_2_4GHZ")
119 {
120 standard = WIFI_STANDARD_80211n;
121 phyBand = WIFI_PHY_BAND_2_4GHZ;
122 channelBand = "BAND_2_4GHZ";
123 ssid = Ssid("ns380211n_2_4GHZ");
124 dataRate = "HtMcs0";
125 freq = 2402 + (bw / 2); // so as to have 2412/2422 for 20/40
126 dataStartTime = MicroSeconds(4700);
127 dataDuration = MicroSeconds(400);
128 if (bw != 20 && bw != 40)
129 {
130 std::cout << "Bandwidth is not compatible with standard" << std::endl;
131 return 1;
132 }
133 }
134 else if (standardStr == "11n_5GHZ")
135 {
136 standard = WIFI_STANDARD_80211n;
137 phyBand = WIFI_PHY_BAND_5GHZ;
138 channelBand = "BAND_5GHZ";
139 ssid = Ssid("ns380211n_5GHZ");
140 dataRate = "HtMcs0";
141 freq = 5170 + (bw / 2); // so as to have 5180/5190 for 20/40
142 dataStartTime = MicroSeconds(1000);
143 if (bw != 20 && bw != 40)
144 {
145 std::cout << "Bandwidth is not compatible with standard" << std::endl;
146 return 1;
147 }
148 }
149 else if (standardStr == "11ac")
150 {
151 standard = WIFI_STANDARD_80211ac;
152 phyBand = WIFI_PHY_BAND_5GHZ;
153 channelBand = "BAND_5GHZ";
154 ssid = Ssid("ns380211ac");
155 dataRate = "VhtMcs0";
156 freq = 5170 + (bw / 2); // so as to have 5180/5190/5210/5250 for 20/40/80/160
157 dataStartTime = MicroSeconds(1100);
158 dataDuration += MicroSeconds(400); // account for ADDBA procedure
159 if (bw != 20 && bw != 40 && bw != 80 && bw != 160)
160 {
161 std::cout << "Bandwidth is not compatible with standard" << std::endl;
162 return 1;
163 }
164 }
165 else if (standardStr == "11ax_2_4GHZ")
166 {
167 standard = WIFI_STANDARD_80211ax;
168 phyBand = WIFI_PHY_BAND_2_4GHZ;
169 channelBand = "BAND_2_4GHZ";
170 ssid = Ssid("ns380211ax_2_4GHZ");
171 dataRate = "HeMcs0";
172 freq = 2402 + (bw / 2); // so as to have 2412/2422/2442 for 20/40/80
173 dataStartTime = MicroSeconds(5500);
174 dataDuration += MicroSeconds(2000); // account for ADDBA procedure
175 if (bw != 20 && bw != 40 && bw != 80)
176 {
177 std::cout << "Bandwidth is not compatible with standard" << std::endl;
178 return 1;
179 }
180 }
181 else if (standardStr == "11ax_5GHZ")
182 {
183 standard = WIFI_STANDARD_80211ax;
184 phyBand = WIFI_PHY_BAND_5GHZ;
185 channelBand = "BAND_5GHZ";
186 ssid = Ssid("ns380211ax_5GHZ");
187 dataRate = "HeMcs0";
188 freq = 5170 + (bw / 2); // so as to have 5180/5190/5210/5250 for 20/40/80/160
189 dataStartTime = MicroSeconds(1200);
190 dataDuration += MicroSeconds(500); // account for ADDBA procedure
191 if (bw != 20 && bw != 40 && bw != 80 && bw != 160)
192 {
193 std::cout << "Bandwidth is not compatible with standard" << std::endl;
194 return 1;
195 }
196 }
197 else
198 {
199 std::cout << "Unknown OFDM standard (please refer to the listed possible values)"
200 << std::endl;
201 return 1;
202 }
203
204 if (verbose)
205 {
207 LogComponentEnable("WifiSpectrumValueHelper", LOG_LEVEL_ALL);
208 LogComponentEnable("SpectrumWifiPhy", LOG_LEVEL_ALL);
209 }
210
211 /* nodes and positions */
212 NodeContainer wifiNodes;
213 NodeContainer spectrumAnalyzerNodes;
214 NodeContainer allNodes;
215 wifiNodes.Create(2);
216 spectrumAnalyzerNodes.Create(1);
217 allNodes.Add(wifiNodes);
218 allNodes.Add(spectrumAnalyzerNodes);
219 NodeContainer wifiStaNode;
221 wifiApNode.Add(wifiNodes.Get(0));
222 wifiStaNode.Add(wifiNodes.Get(1));
223
224 /* channel and propagation */
226 channelHelper.SetChannel("ns3::MultiModelSpectrumChannel");
227 // constant path loss added just to show capability to set different propagation loss models
228 // FriisSpectrumPropagationLossModel already added by default in SpectrumChannelHelper
229 channelHelper.AddSpectrumPropagationLoss("ns3::ConstantSpectrumPropagationLossModel");
230 Ptr<SpectrumChannel> channel = channelHelper.Create();
231
232 /* Wi-Fi transmitter setup */
233
234 SpectrumWifiPhyHelper spectrumPhy;
235 spectrumPhy.SetChannel(channel);
236 spectrumPhy.SetErrorRateModel("ns3::NistErrorRateModel");
237 spectrumPhy.Set("TxPowerStart", DoubleValue(pow)); // dBm
238 spectrumPhy.Set("TxPowerEnd", DoubleValue(pow));
239 auto channelNumber = WifiPhyOperatingChannel::FindFirst(0, freq, bw, standard, phyBand)->number;
240 std::ostringstream channelSettings;
241 channelSettings << "{" << +channelNumber << ", " << bw << ", " << channelBand << ", 0}";
242 spectrumPhy.Set("ChannelSettings", StringValue(channelSettings.str()));
243
245 wifi.SetStandard(standard);
246 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
247 "DataMode",
248 StringValue(dataRate),
249 "ControlMode",
250 StringValue(dataRate));
251
252 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid), "ActiveProbing", BooleanValue(false));
253 NetDeviceContainer staDevice = wifi.Install(spectrumPhy, mac, wifiStaNode);
254 mac.SetType("ns3::ApWifiMac",
255 "Ssid",
256 SsidValue(ssid),
257 "EnableBeaconJitter",
258 BooleanValue(false)); // so as to be sure that first beacon arrives quickly
259 NetDeviceContainer apDevice = wifi.Install(spectrumPhy, mac, wifiApNode);
260
263 nodePositionList->Add(Vector(0.0, 1.0, 0.0)); // AP
264 nodePositionList->Add(Vector(1.0, 0.0, 0.0)); // STA
265 nodePositionList->Add(Vector(0.0, 0.0, 0.0)); // Spectrum Analyzer
266 mobility.SetPositionAllocator(nodePositionList);
267 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
268 mobility.Install(allNodes);
269
270 /* Need to send data packet because beacon and association frames shall be sent using lowest
271 * rate */
272 // Send one data packet (this packet is sent using data rate / MCS defined above) once
273 // association is done (otherwise dropped)
274 Simulator::Schedule(dataStartTime,
275 &SendPacket,
276 apDevice.Get(0),
277 staDevice.Get(0)->GetAddress());
278
279 /* frequency range for spectrum analyzer */
280 std::vector<double> freqs;
281 int margin = 2; // 1MHz margin on each side
282 int band = (bw + margin);
283 freqs.reserve(4 * 10 * band);
284 for (int i = 0; i < (4 * 10 * band); ++i) // conversion to 100kHz scale
285 {
286 freqs.push_back(i * 1e5 + (freq - 2 * band) * 1e6);
287 }
288 Ptr<SpectrumModel> spectrumAnalyzerFreqModel = Create<SpectrumModel>(freqs);
289
290 /* spectrum analyzer setup */
291 SpectrumAnalyzerHelper spectrumAnalyzerHelper;
292 spectrumAnalyzerHelper.SetChannel(channel);
293 spectrumAnalyzerHelper.SetRxSpectrumModel(spectrumAnalyzerFreqModel);
294 spectrumAnalyzerHelper.SetPhyAttribute(
295 "Resolution",
296 TimeValue(MicroSeconds(4))); // enough resolution to distinguish OFDM symbols (default 1ms
297 // too long even for PPDUs)
298 std::ostringstream ossFileName;
299 ossFileName << "spectrum-analyzer-wifi-" << standardStr << "-" << bw << "MHz";
300 spectrumAnalyzerHelper.EnableAsciiAll(ossFileName.str());
301 NetDeviceContainer spectrumAnalyzerDevices =
302 spectrumAnalyzerHelper.Install(spectrumAnalyzerNodes);
303
304 /* Let enough time for first beacon, association procedure, and first data (+acknowledgment and
305 * eventually preceding ADDBA procedure) */
306 Simulator::Stop(dataStartTime + dataDuration);
307
309
310 /* Plot transmitted spectra with Gnuplot */
311 ossFileName << "-2-0"; // append node-interface info
312 std::ostringstream ossPlt;
313 ossPlt << ossFileName.str() << ".plt";
314 std::ofstream plotFile(ossPlt.str());
315 std::ostringstream ossPng;
316 ossPng << ossFileName.str() << ".png";
317 Gnuplot plot = Gnuplot(ossPng.str());
318 // Prepare 3D plot (reset previous values)
319 std::ostringstream ossExtra;
320 ossExtra << "file = '" << ossFileName.str() << "'";
321 plot.SetExtra(ossExtra.str());
322 plot.AppendExtra("unset surface");
323 plot.AppendExtra("set key off");
324 // Configure output file as png
325 plot.AppendExtra("set term png");
326 plot.AppendExtra("set output file . '.png'");
327 // Switch to 3D plot
328 plot.AppendExtra("set pm3d at s");
329 plot.AppendExtra("set palette");
330 // Orient view
331 plot.AppendExtra("set view 50,50");
332 // Add legends
333 plot.AppendExtra("set xlabel \"time (ms)\"");
334 plot.AppendExtra("set ylabel \"freq (MHz)\" offset 15,0,0");
335 plot.AppendExtra("set zlabel \"PSD (dBW/Hz)\" offset 15,0,0");
336 // Define grid
337 plot.AppendExtra("set ytics");
338 plot.AppendExtra("set mytics 2");
339 plot.AppendExtra("set ztics");
340 plot.AppendExtra("set mztics 5");
341 plot.AppendExtra("set grid ytics mytics ztics mztics");
342 // tr file name
343 plot.AppendExtra("filename = file . '.tr'");
344 // Extract max power using stats (so as to normalize during display)
345 plot.AppendExtra("stats filename using 3");
346 plot.AppendExtra("refW = STATS_max");
347 // Plot graph (file being defined upon gnuplot call)
348 plot.AppendExtra("splot filename using ($1*1000.0):($2/1e6):(10*log10($3/refW))");
349 // Generate output and close file
350 plot.GenerateOutput(plotFile);
351 plotFile.close();
352
354
355 std::cout << "Simulation done!" << std::endl;
356 std::cout << "See spectrum analyzer output file: " << ossFileName.str() << ".tr" << std::endl;
357 std::cout << "To generate plot simply execute the following command: gnuplot "
358 << ossFileName.str() << ".plt" << std::endl;
359
360 return 0;
361}
a polymophic address class
Definition address.h:90
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition gnuplot.h:359
void AppendExtra(const std::string &extra)
Definition gnuplot.cc:778
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition gnuplot.cc:791
void SetExtra(const std::string &extra)
Definition gnuplot.cc:772
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Class to allow the Spectrum Analysis.
NetDeviceContainer Install(NodeContainer c) const
void SetPhyAttribute(std::string name, const AttributeValue &v)
void SetChannel(Ptr< SpectrumChannel > channel)
Set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper.
void EnableAsciiAll(std::string prefix)
Enable ASCII output.
void SetRxSpectrumModel(Ptr< SpectrumModel > m)
Set the spectrum model used by the created SpectrumAnalyzer instances to represent incoming signals.
Setup a SpectrumChannel.
Ptr< SpectrumChannel > Create() const
static SpectrumChannelHelper Default()
Setup a default SpectrumChannel.
void AddSpectrumPropagationLoss(std::string name, Ts &&... args)
void SetChannel(std::string type, Ts &&... args)
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(const Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
helps to create WifiNetDevice objects
create MAC layers for a ns3::WifiNetDevice.
void Set(std::string name, const AttributeValue &v)
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first frequency segment matching the specified parameters.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition log.cc:291
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:105
@ LOG_PREFIX_ALL
All prefixes.
Definition log.h:111
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition log.cc:309
ssid
Definition third.py:82
channel
Definition third.py:77
mac
Definition third.py:81
wifi
Definition third.py:84
wifiApNode
Definition third.py:75
mobility
Definition third.py:92
bool verbose
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...