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_2_4GHZ);
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_5GHZ);
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_2_4GHZ);
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_5GHZ);
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 
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 }
Class to allow the Spectrum Analysis.
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:143
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
void AppendExtra(const std::string &extra)
Definition: gnuplot.cc:749
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Hold variables of type string.
Definition: string.h:41
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
cmd
Definition: second.py:35
helps to create WifiNetDevice objects
Definition: wifi-helper.h:318
a polymophic address class
Definition: address.h:90
channel
Definition: third.py:92
mobility
Definition: third.py:108
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:371
static SpectrumWifiPhyHelper Default(void)
Create a PHY helper in a default working state.
AttributeValue implementation for Time.
Definition: nstime.h:1342
All prefixes.
Definition: log.h:122
void SetChannel(Ptr< SpectrumChannel > channel)
Hold an unsigned integer type.
Definition: uinteger.h:44
ssid
Definition: third.py:100
holds a vector of ns3::NetDevice pointers
mac
Definition: third.py:99
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:762
wifiApNode
Definition: third.py:90
Parse command-line arguments.
Definition: command-line.h:226
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
void LogComponentEnableAll(enum LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:385
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
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())
create MAC layers for a ns3::WifiNetDevice.
void SetErrorRateModel(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())
Definition: wifi-helper.cc:149
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:743
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
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())
void SendPacket(Ptr< NetDevice > sourceDevice, Address &destination)
This example (inspired from tv-trans-example) enables to generate the transmitted spectra of Wi-Fi st...
wifi
Definition: third.py:96
Helper class used to assign positions and mobility models to nodes.
static SpectrumChannelHelper Default()
Setup a default SpectrumChannel.
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
AttributeValue implementation for Ssid.
Definition: ssid.h:105
void Add(Vector v)
Add a position to the list of positions.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void SetChannel(Ptr< SpectrumChannel > channel)
Set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper...
Print everything.
Definition: log.h:116
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1294
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Setup a SpectrumChannel.
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
Ptr< SpectrumChannel > Create(void) const
bool verbose
Make it easy to create and manage PHY objects for the spectrum model.