A Discrete-Event Network Simulator
API
wifi-trans-example.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2017 Orange Labs
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: Rediet <getachew.redieteab@orange.com>
19  */
20 
21 #include "ns3/gnuplot.h"
22 #include "ns3/command-line.h"
23 #include "ns3/string.h"
24 #include "ns3/ssid.h"
25 #include "ns3/spectrum-helper.h"
26 #include "ns3/spectrum-wifi-helper.h"
27 #include "ns3/spectrum-analyzer-helper.h"
28 #include "ns3/spectrum-channel.h"
29 #include "ns3/mobility-helper.h"
30 
31 using namespace ns3;
32 
47 void
48 SendPacket (Ptr<NetDevice> sourceDevice, Address& destination)
49 {
50  Ptr<Packet> pkt = Create<Packet> (100); // dummy bytes of data
51  sourceDevice->Send (pkt, destination, 0);
52 }
53 
54 int main (int argc, char** argv)
55 {
56  std::string standard = "11a";
57  int bw = 20;
58  double pow = 23; //dBm
59  bool verbose = false;
60  CommandLine cmd (__FILE__);
61  cmd.AddValue ("standard",
62  "OFDM-based Wi-Fi standard [11a, 11p_10MHZ, 11p_5MHZ, 11n_2_4GHZ, 11n_5GHZ, 11ac, 11ax_2_4GHZ, 11ax_5GHZ]",
63  standard);
64  cmd.AddValue ("bw", "Bandwidth (consistent with standard, in MHz)", bw);
65  cmd.AddValue ("txPower", "Transmit power (dBm)", pow);
66  cmd.AddValue ("verbose", "Display log messages for WifiSpectrumValueHelper and SpectrumWifiPhy", verbose);
67  cmd.Parse (argc,argv);
68 
70  Ssid ssid;
71  std::string dataRate;
72  int freq;
73  Time dataStartTime = MicroSeconds (800); // leaving enough time for beacon and association procedure
74  Time dataDuration = MicroSeconds (300); // leaving enough time for data transfer (+ acknowledgment)
75  if (standard == "11a")
76  {
77  wifi.SetStandard (WIFI_STANDARD_80211a);
78  ssid = Ssid ("ns380211a");
79  dataRate = "OfdmRate6Mbps";
80  freq = 5180;
81  if (bw != 20)
82  {
83  std::cout << "Bandwidth is not compatible with standard" << std::endl;
84  return 1;
85  }
86  }
87  else if (standard == "11p_10MHZ")
88  {
89  wifi.SetStandard (WIFI_STANDARD_80211p);
90  ssid = Ssid ("ns380211p_10MHZ");
91  dataRate = "OfdmRate3MbpsBW10MHz";
92  freq = 5860;
93  dataStartTime = MicroSeconds (1400);
94  dataDuration = MicroSeconds (600);
95  if (bw != 10)
96  {
97  std::cout << "Bandwidth is not compatible with standard" << std::endl;
98  return 1;
99  }
100  }
101  else if (standard == "11p_5MHZ")
102  {
103  wifi.SetStandard (WIFI_STANDARD_80211p);
104  ssid = Ssid ("ns380211p_5MHZ");
105  dataRate = "OfdmRate1_5MbpsBW5MHz";
106  freq = 5860;
107  dataStartTime = MicroSeconds (2500);
108  dataDuration = MicroSeconds (1200);
109  if (bw != 5)
110  {
111  std::cout << "Bandwidth is not compatible with standard" << std::endl;
112  return 1;
113  }
114  }
115  else if (standard == "11n_2_4GHZ")
116  {
117  wifi.SetStandard (WIFI_STANDARD_80211n);
118  ssid = Ssid ("ns380211n_2_4GHZ");
119  dataRate = "HtMcs0";
120  freq = 2402 + (bw / 2); //so as to have 2412/2422 for 20/40
121  dataStartTime = MicroSeconds (4700);
122  dataDuration = MicroSeconds (400);
123  if (bw != 20 && bw != 40)
124  {
125  std::cout << "Bandwidth is not compatible with standard" << std::endl;
126  return 1;
127  }
128  }
129  else if (standard == "11n_5GHZ")
130  {
131  wifi.SetStandard (WIFI_STANDARD_80211n);
132  ssid = Ssid ("ns380211n_5GHZ");
133  dataRate = "HtMcs0";
134  freq = 5170 + (bw / 2); //so as to have 5180/5190 for 20/40
135  dataStartTime = MicroSeconds (1000);
136  if (bw != 20 && bw != 40)
137  {
138  std::cout << "Bandwidth is not compatible with standard" << std::endl;
139  return 1;
140  }
141  }
142  else if (standard == "11ac")
143  {
144  wifi.SetStandard (WIFI_STANDARD_80211ac);
145  ssid = Ssid ("ns380211ac");
146  dataRate = "VhtMcs0";
147  freq = 5170 + (bw / 2); //so as to have 5180/5190/5210/5250 for 20/40/80/160
148  dataStartTime = MicroSeconds (1100);
149  dataDuration += MicroSeconds (400); //account for ADDBA procedure
150  if (bw != 20 && bw != 40 && bw != 80 && bw != 160)
151  {
152  std::cout << "Bandwidth is not compatible with standard" << std::endl;
153  return 1;
154  }
155  }
156  else if (standard == "11ax_2_4GHZ")
157  {
158  wifi.SetStandard (WIFI_STANDARD_80211ax);
159  ssid = Ssid ("ns380211ax_2_4GHZ");
160  dataRate = "HeMcs0";
161  freq = 2402 + (bw / 2); //so as to have 2412/2422/2442 for 20/40/80
162  dataStartTime = MicroSeconds (5500);
163  dataDuration += MicroSeconds (2000); //account for ADDBA procedure
164  if (bw != 20 && bw != 40 && bw != 80)
165  {
166  std::cout << "Bandwidth is not compatible with standard" << std::endl;
167  return 1;
168  }
169  }
170  else if (standard == "11ax_5GHZ")
171  {
172  wifi.SetStandard (WIFI_STANDARD_80211ax);
173  ssid = Ssid ("ns380211ax_5GHZ");
174  dataRate = "HeMcs0";
175  freq = 5170 + (bw / 2); //so as to have 5180/5190/5210/5250 for 20/40/80/160
176  dataStartTime = MicroSeconds (1200);
177  dataDuration += MicroSeconds (500); //account for ADDBA procedure
178  if (bw != 20 && bw != 40 && bw != 80 && bw != 160)
179  {
180  std::cout << "Bandwidth is not compatible with standard" << std::endl;
181  return 1;
182  }
183  }
184  else
185  {
186  std::cout << "Unknown OFDM standard (please refer to the listed possible values)" << std::endl;
187  return 1;
188  }
189 
190  if (verbose)
191  {
193  LogComponentEnable ("WifiSpectrumValueHelper", LOG_LEVEL_ALL);
194  LogComponentEnable ("SpectrumWifiPhy", LOG_LEVEL_ALL);
195  }
196 
197  /* nodes and positions */
198  NodeContainer wifiNodes;
199  NodeContainer spectrumAnalyzerNodes;
200  NodeContainer allNodes;
201  wifiNodes.Create (2);
202  spectrumAnalyzerNodes.Create (1);
203  allNodes.Add (wifiNodes);
204  allNodes.Add (spectrumAnalyzerNodes);
205  NodeContainer wifiStaNode;
207  wifiApNode.Add (wifiNodes.Get (0));
208  wifiStaNode.Add (wifiNodes.Get (1));
209 
210  /* channel and propagation */
212  channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel");
213  // constant path loss added just to show capability to set different propagation loss models
214  // FriisSpectrumPropagationLossModel already added by default in SpectrumChannelHelper
215  channelHelper.AddSpectrumPropagationLoss ("ns3::ConstantSpectrumPropagationLossModel");
216  Ptr<SpectrumChannel> channel = channelHelper.Create ();
217 
218  /* Wi-Fi transmitter setup */
219 
220  SpectrumWifiPhyHelper spectrumPhy;
221  spectrumPhy.SetChannel (channel);
222  spectrumPhy.SetErrorRateModel ("ns3::NistErrorRateModel");
223  spectrumPhy.Set ("Frequency", UintegerValue (freq));
224  spectrumPhy.Set ("ChannelWidth", UintegerValue (bw));
225  spectrumPhy.Set ("TxPowerStart", DoubleValue (pow)); // dBm
226  spectrumPhy.Set ("TxPowerEnd", DoubleValue (pow));
227 
229  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", StringValue (dataRate),
230  "ControlMode", StringValue (dataRate));
231 
232  mac.SetType ("ns3::StaWifiMac",
233  "Ssid", SsidValue (ssid),
234  "ActiveProbing", BooleanValue (false));
235  NetDeviceContainer staDevice = wifi.Install (spectrumPhy, mac, wifiStaNode);
236  mac.SetType ("ns3::ApWifiMac",
237  "Ssid", SsidValue (ssid),
238  "EnableBeaconJitter", BooleanValue (false)); // so as to be sure that first beacon arrives quickly
239  NetDeviceContainer apDevice = wifi.Install (spectrumPhy, mac, wifiApNode);
240 
242  Ptr<ListPositionAllocator> nodePositionList = CreateObject<ListPositionAllocator> ();
243  nodePositionList->Add (Vector (0.0, 1.0, 0.0)); // AP
244  nodePositionList->Add (Vector (1.0, 0.0, 0.0)); // STA
245  nodePositionList->Add (Vector (0.0, 0.0, 0.0)); // Spectrum Analyzer
246  mobility.SetPositionAllocator (nodePositionList);
247  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
248  mobility.Install (allNodes);
249 
250  /* Need to send data packet because beacon and association frames shall be sent using lowest rate */
251  // Send one data packet (this packet is sent using data rate / MCS defined above) once association is done (otherwise dropped)
252  Simulator::Schedule (dataStartTime, &SendPacket, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
253 
254  /* frequency range for spectrum analyzer */
255  std::vector<double> freqs;
256  int margin = 2; //1MHz margin on each side
257  int band = (bw + margin);
258  for (int i = 0; i < (4 * 10 * band); ++i) //conversion to 100kHz scale
259  {
260  freqs.push_back (i * 1e5 + (freq - 2 * band) * 1e6);
261  }
262  Ptr<SpectrumModel> spectrumAnalyzerFreqModel = Create<SpectrumModel> (freqs);
263 
264  /* spectrum analyzer setup */
265  SpectrumAnalyzerHelper spectrumAnalyzerHelper;
266  spectrumAnalyzerHelper.SetChannel (channel);
267  spectrumAnalyzerHelper.SetRxSpectrumModel (spectrumAnalyzerFreqModel);
268  spectrumAnalyzerHelper.SetPhyAttribute ("Resolution", TimeValue (MicroSeconds (4))); //enough resolution to distinguish OFDM symbols (default 1ms too long even for PPDUs)
269  std::ostringstream ossFileName;
270  ossFileName << "spectrum-analyzer-wifi-" << standard << "-" << bw << "MHz";
271  spectrumAnalyzerHelper.EnableAsciiAll (ossFileName.str ());
272  NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes);
273 
274  /* Let enough time for first beacon, association procedure, and first data (+acknowledgment and eventually preceding ADDBA procedure) */
275  Simulator::Stop (dataStartTime + dataDuration);
276 
277  Simulator::Run ();
278 
279  /* Plot transmitted spectra with Gnuplot */
280  ossFileName << "-2-0"; // append node-interface info
281  std::ostringstream ossPlt;
282  ossPlt << ossFileName.str () << ".plt";
283  std::ofstream plotFile (ossPlt.str ());
284  std::ostringstream ossPng;
285  ossPng << ossFileName.str () << ".png";
286  Gnuplot plot = Gnuplot (ossPng.str ());
287  //Prepare 3D plot (reset previous values)
288  std::ostringstream ossExtra;
289  ossExtra << "file = '" << ossFileName.str () << "'";
290  plot.SetExtra (ossExtra.str ());
291  plot.AppendExtra ("unset surface");
292  plot.AppendExtra ("set key off");
293  //Configure output file as png
294  plot.AppendExtra ("set term png");
295  plot.AppendExtra ("set output file . '.png'");
296  //Switch to 3D plot
297  plot.AppendExtra ("set pm3d at s");
298  plot.AppendExtra ("set palette");
299  //Orient view
300  plot.AppendExtra ("set view 50,50");
301  //Add legends
302  plot.AppendExtra ("set xlabel \"time (ms)\"");
303  plot.AppendExtra ("set ylabel \"freq (MHz)\" offset 15,0,0");
304  plot.AppendExtra ("set zlabel \"PSD (dBW/Hz)\" offset 15,0,0");
305  //Define grid
306  plot.AppendExtra ("set ytics");
307  plot.AppendExtra ("set mytics 2");
308  plot.AppendExtra ("set ztics");
309  plot.AppendExtra ("set mztics 5");
310  plot.AppendExtra ("set grid ytics mytics ztics mztics");
311  //tr file name
312  plot.AppendExtra ("filename = file . '.tr'");
313  //Extract max power using stats (so as to normalize during display)
314  plot.AppendExtra ("stats filename using 3");
315  plot.AppendExtra ("refW = STATS_max");
316  //Plot graph (file being defined upon gnuplot call)
317  plot.AppendExtra ("splot filename using ($1*1000.0):($2/1e6):(10*log10($3/refW))");
318  //Generate output and close file
319  plot.GenerateOutput (plotFile);
320  plotFile.close ();
321 
323 
324  std::cout << "Simulation done!" << std::endl;
325  std::cout << "See spectrum analyzer output file: " << ossFileName.str () << ".tr" << std::endl;
326  std::cout << "To generate plot simply execute the following command: gnuplot " << ossFileName.str () << ".plt" << std::endl;
327 
328  return 0;
329 }
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:373
void AppendExtra(const std::string &extra)
Definition: gnuplot.cc:753
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:766
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:747
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.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
virtual Address GetAddress(void) const =0
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(NodeContainer other)
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.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
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.
void SetChannel(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())
void AddSpectrumPropagationLoss(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())
static SpectrumChannelHelper Default()
Setup a default SpectrumChannel.
Ptr< SpectrumChannel > Create(void) const
Make it easy to create and manage PHY objects for the spectrum model.
void SetChannel(Ptr< SpectrumChannel > channel)
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:105
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:274
create MAC layers for a ns3::WifiNetDevice.
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:154
void SetErrorRateModel(std::string type, Args &&... args)
Helper function used to set the error rate model.
Definition: wifi-helper.h:440
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116
@ LOG_PREFIX_ALL
All prefixes.
Definition: log.h:122
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
void LogComponentEnableAll(enum LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:385
cmd
Definition: second.py:35
ssid
Definition: third.py:100
channel
Definition: third.py:92
mac
Definition: third.py:99
wifi
Definition: third.py:96
wifiApNode
Definition: third.py:90
mobility
Definition: third.py:108
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...