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 <iostream>
22 #include <stdlib.h>
23 #include "ns3/core-module.h"
24 #include "ns3/wifi-module.h"
25 #include "ns3/mobility-module.h"
26 #include "ns3/spectrum-module.h"
27 #include "ns3/gnuplot.h"
28 
29 using namespace ns3;
30 
45 void
46 SendPacket (Ptr<NetDevice> sourceDevice, Address& destination)
47 {
48  Ptr<Packet> pkt = Create<Packet> (100); // dummy bytes of data
49  sourceDevice->Send (pkt, destination, 0);
50 }
51 
52 int main (int argc, char** argv)
53 {
54  std::string standard = "11a";
55  int bw = 20;
56  double pow = 23; //dBm
57  bool verbose = false;
59  cmd.AddValue ("standard",
60  "OFDM-based Wi-Fi standard [11a, 11_10MHZ, 11_5MHZ, 11n_2_4GHZ, 11n_5GHZ, 11ac, 11ax_2_4GHZ, 11ax_5GHZ]",
61  standard);
62  cmd.AddValue ("bw", "Bandwidth (consistent with standard, in MHz)", bw);
63  cmd.AddValue ("txPower", "Transmit power (dBm)", pow);
64  cmd.AddValue ("verbose", "Display log messages for WifiSpectrumValueHelper and SpectrumWifiPhy", verbose);
65  cmd.Parse (argc,argv);
66 
68  Ssid ssid;
69  std::string dataRate;
70  int freq;
71  Time dataStartTime = MicroSeconds (800); // leaving enough time for beacon and association procedure
72  Time dataDuration = MicroSeconds (300); // leaving enough time for data transfer (+ acknowledgment)
73  if (standard == "11a")
74  {
76  ssid = Ssid ("ns380211a");
77  dataRate = "OfdmRate6Mbps";
78  freq = 5180;
79  if (bw != 20)
80  {
81  std::cout << "Bandwidth is not compatible with standard" << std::endl;
82  return 1;
83  }
84  }
85  else if (standard == "11_10MHZ")
86  {
88  ssid = Ssid ("ns380211_10MHZ");
89  dataRate = "OfdmRate3MbpsBW10MHz";
90  freq = 5860;
91  dataStartTime = MicroSeconds (1400);
92  dataDuration = MicroSeconds (600);
93  if (bw != 10)
94  {
95  std::cout << "Bandwidth is not compatible with standard" << std::endl;
96  return 1;
97  }
98  }
99  else if (standard == "11_5MHZ")
100  {
102  ssid = Ssid ("ns380211_5MHZ");
103  dataRate = "OfdmRate1_5MbpsBW5MHz";
104  freq = 5860;
105  dataStartTime = MicroSeconds (2500);
106  dataDuration = MicroSeconds (1200);
107  if (bw != 5)
108  {
109  std::cout << "Bandwidth is not compatible with standard" << std::endl;
110  return 1;
111  }
112  }
113  else if (standard == "11n_2_4GHZ")
114  {
116  ssid = Ssid ("ns380211n_2_4GHZ");
117  dataRate = "HtMcs0";
118  freq = 2402 + (bw / 2); //so as to have 2412/2422 for 20/40
119  dataStartTime = MicroSeconds (4700);
120  dataDuration = MicroSeconds (400);
121  if (bw != 20 && bw != 40)
122  {
123  std::cout << "Bandwidth is not compatible with standard" << std::endl;
124  return 1;
125  }
126  }
127  else if (standard == "11n_5GHZ")
128  {
130  ssid = Ssid ("ns380211n_5GHZ");
131  dataRate = "HtMcs0";
132  freq = 5170 + (bw / 2); //so as to have 5180/5190 for 20/40
133  dataStartTime = MicroSeconds (1000);
134  if (bw != 20 && bw != 40)
135  {
136  std::cout << "Bandwidth is not compatible with standard" << std::endl;
137  return 1;
138  }
139  }
140  else if (standard == "11ac")
141  {
143  ssid = Ssid ("ns380211ac");
144  dataRate = "VhtMcs0";
145  freq = 5170 + (bw / 2); //so as to have 5180/5190/5210/5250 for 20/40/80/160
146  dataStartTime = MicroSeconds (1100);
147  dataDuration += MicroSeconds (400); //account for ADDBA procedure
148  if (bw != 20 && bw != 40 && bw != 80 && bw != 160)
149  {
150  std::cout << "Bandwidth is not compatible with standard" << std::endl;
151  return 1;
152  }
153  }
154  else if (standard == "11ax_2_4GHZ")
155  {
157  ssid = Ssid ("ns380211ax_2_4GHZ");
158  dataRate = "HeMcs0";
159  freq = 2402 + (bw / 2); //so as to have 2412/2422/2442 for 20/40/80
160  dataStartTime = MicroSeconds (5500);
161  dataDuration += MicroSeconds (2000); //account for ADDBA procedure
162  if (bw != 20 && bw != 40 && bw != 80)
163  {
164  std::cout << "Bandwidth is not compatible with standard" << std::endl;
165  return 1;
166  }
167  }
168  else if (standard == "11ax_5GHZ")
169  {
171  ssid = Ssid ("ns380211ax_5GHZ");
172  dataRate = "HeMcs0";
173  freq = 5170 + (bw / 2); //so as to have 5180/5190/5210/5250 for 20/40/80/160
174  dataStartTime = MicroSeconds (1200);
175  dataDuration += MicroSeconds (500); //account for ADDBA procedure
176  if (bw != 20 && bw != 40 && bw != 80 && bw != 160)
177  {
178  std::cout << "Bandwidth is not compatible with standard" << std::endl;
179  return 1;
180  }
181  }
182  else
183  {
184  std::cout << "Unknown OFDM standard (please refer to the listed possible values)" << std::endl;
185  return 1;
186  }
187 
188  if (verbose)
189  {
191  LogComponentEnable ("WifiSpectrumValueHelper", LOG_LEVEL_ALL);
192  LogComponentEnable ("SpectrumWifiPhy", LOG_LEVEL_ALL);
193  }
194 
195  /* nodes and positions */
196  NodeContainer wifiNodes;
197  NodeContainer spectrumAnalyzerNodes;
198  NodeContainer allNodes;
199  wifiNodes.Create (2);
200  spectrumAnalyzerNodes.Create (1);
201  allNodes.Add (wifiNodes);
202  allNodes.Add (spectrumAnalyzerNodes);
203  NodeContainer wifiStaNode;
205  wifiApNode.Add (wifiNodes.Get (0));
206  wifiStaNode.Add (wifiNodes.Get (1));
207 
208  /* channel and propagation */
210  channelHelper.SetChannel ("ns3::MultiModelSpectrumChannel");
211  // constant path loss added just to show capability to set different propagation loss models
212  // FriisSpectrumPropagationLossModel already added by default in SpectrumChannelHelper
213  channelHelper.AddSpectrumPropagationLoss ("ns3::ConstantSpectrumPropagationLossModel");
214  Ptr<SpectrumChannel> channel = channelHelper.Create ();
215 
216  /* Wi-Fi transmitter setup */
217 
219  spectrumPhy.SetChannel (channel);
220  spectrumPhy.SetErrorRateModel ("ns3::NistErrorRateModel");
221  spectrumPhy.Set ("Frequency", UintegerValue (freq));
222  spectrumPhy.Set ("ChannelWidth", UintegerValue (bw));
223  spectrumPhy.Set ("TxPowerStart", DoubleValue (pow)); // dBm
224  spectrumPhy.Set ("TxPowerEnd", DoubleValue (pow));
225 
227  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager","DataMode", StringValue (dataRate),
228  "ControlMode", StringValue (dataRate));
229 
230  mac.SetType ("ns3::StaWifiMac",
231  "Ssid", SsidValue (ssid),
232  "ActiveProbing", BooleanValue (false));
233  NetDeviceContainer staDevice = wifi.Install (spectrumPhy, mac, wifiStaNode);
234  mac.SetType ("ns3::ApWifiMac",
235  "Ssid", SsidValue (ssid),
236  "EnableBeaconJitter", BooleanValue (false)); // so as to be sure that first beacon arrives quickly
237  NetDeviceContainer apDevice = wifi.Install (spectrumPhy, mac, wifiApNode);
238 
240  Ptr<ListPositionAllocator> nodePositionList = CreateObject<ListPositionAllocator> ();
241  nodePositionList->Add (Vector (0.0, 1.0, 0.0)); // AP
242  nodePositionList->Add (Vector (1.0, 0.0, 0.0)); // STA
243  nodePositionList->Add (Vector (0.0, 0.0, 0.0)); // Spectrum Analyzer
244  mobility.SetPositionAllocator (nodePositionList);
245  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
246  mobility.Install (allNodes);
247 
248  /* Need to send data packet because beacon and association frames shall be sent using lowest rate */
249  // Send one data packet (this packet is sent using data rate / MCS defined above) once association is done (otherwise dropped)
250  Simulator::Schedule (dataStartTime, &SendPacket, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
251 
252  /* frequency range for spectrum analyzer */
253  std::vector<double> freqs;
254  int margin = 2; //1MHz margin on each side
255  int band = (bw + margin);
256  for (int i = 0; i < (4 * 10 * band); ++i) //conversion to 100kHz scale
257  {
258  freqs.push_back (i * 1e5 + (freq - 2 * band) * 1e6);
259  }
260  Ptr<SpectrumModel> spectrumAnalyzerFreqModel = Create<SpectrumModel> (freqs);
261 
262  /* spectrum analyzer setup */
263  SpectrumAnalyzerHelper spectrumAnalyzerHelper;
264  spectrumAnalyzerHelper.SetChannel (channel);
265  spectrumAnalyzerHelper.SetRxSpectrumModel (spectrumAnalyzerFreqModel);
266  spectrumAnalyzerHelper.SetPhyAttribute ("Resolution", TimeValue (MicroSeconds (4))); //enough resolution to distinguish OFDM symbols (default 1ms too long even for PPDUs)
267  std::ostringstream ossFileName;
268  ossFileName << "spectrum-analyzer-wifi-" << standard << "-" << bw << "MHz";
269  spectrumAnalyzerHelper.EnableAsciiAll (ossFileName.str ());
270  NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install (spectrumAnalyzerNodes);
271 
272  /* Let enough time for first beacon, association procedure, and first data (+acknowledgment and eventually preceding ADDBA procedure) */
273  Simulator::Stop (dataStartTime + dataDuration);
274 
275  Simulator::Run ();
276 
277  /* Plot transmitted spectra with Gnuplot */
278  ossFileName << "-2-0"; // append node-interface info
279  std::ostringstream ossPlt;
280  ossPlt << ossFileName.str () << ".plt";
281  std::ofstream plotFile (ossPlt.str ());
282  std::ostringstream ossPng;
283  ossPng << ossFileName.str () << ".png";
284  Gnuplot plot = Gnuplot (ossPng.str ());
285  //Prepare 3D plot (reset previous values)
286  std::ostringstream ossExtra;
287  ossExtra << "file = '" << ossFileName.str () << "'";
288  plot.SetExtra (ossExtra.str ());
289  plot.AppendExtra ("unset surface");
290  plot.AppendExtra ("set key off");
291  //Configure output file as png
292  plot.AppendExtra ("set term png");
293  plot.AppendExtra ("set output file . '.png'");
294  //Switch to 3D plot
295  plot.AppendExtra ("set pm3d at s");
296  plot.AppendExtra ("set palette");
297  //Orient view
298  plot.AppendExtra ("set view 50,50");
299  //Add legends
300  plot.AppendExtra ("set xlabel \"time (ms)\"");
301  plot.AppendExtra ("set ylabel \"freq (MHz)\" offset 15,0,0");
302  plot.AppendExtra ("set zlabel \"PSD (dBW/Hz)\" offset 15,0,0");
303  //Define grid
304  plot.AppendExtra ("set ytics");
305  plot.AppendExtra ("set mytics 2");
306  plot.AppendExtra ("set ztics");
307  plot.AppendExtra ("set mztics 5");
308  plot.AppendExtra ("set grid ytics mytics ztics mztics");
309  //tr file name
310  plot.AppendExtra ("filename = file . '.tr'");
311  //Extract max power using stats (so as to normalize during display)
312  plot.AppendExtra ("stats filename using 3");
313  plot.AppendExtra ("refW = STATS_max");
314  //Plot graph (file being defined upon gnuplot call)
315  plot.AppendExtra ("splot filename using ($1*1000.0):($2/1e6):(10*log10($3/refW))");
316  //Generate output and close file
317  plot.GenerateOutput (plotFile);
318  plotFile.close ();
319 
321 
322  std::cout << "Simulation done!" << std::endl;
323  std::cout << "See spectrum analyzer output file: " << ossFileName.str () << ".tr" << std::endl;
324  std::cout << "To generate plot simply execute the following command: gnuplot " << ossFileName.str () << ".plt" << std::endl;
325 
326  return 0;
327 }
Class to allow the Spectrum Analysis.
tuple channel
Definition: third.py:85
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:133
void AppendExtra(const std::string &extra)
Definition: gnuplot.cc:749
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
OFDM PHY for the 5 GHz band (Clause 17 with 5 MHz channel bandwidth)
AttributeValue implementation for Boolean.
Definition: boolean.h:36
HT PHY for the 5 GHz band (clause 20)
void SetRemoteStationManager(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())
Definition: wifi-helper.cc:700
Hold variables of type string.
Definition: string.h:41
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
Ptr< SpectrumChannel > Create(void) const
HE PHY for the 2.4 GHz band (clause 26)
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
HT PHY for the 2.4 GHz band (clause 20)
helps to create WifiNetDevice objects
Definition: wifi-helper.h:213
tuple cmd
Definition: second.py:35
a polymophic address class
Definition: address.h:90
virtual void SetStandard(WifiPhyStandard standard)
Definition: wifi-helper.cc:723
HE PHY for the 5 GHz band (clause 26)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:369
tuple mobility
Definition: third.py:101
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
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:1069
void SetChannel(Ptr< SpectrumChannel > channel)
Hold an unsigned integer type.
Definition: uinteger.h:44
holds a vector of ns3::NetDevice pointers
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer::Iterator first, NodeContainer::Iterator last) const
Definition: wifi-helper.cc:729
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:762
tuple mac
Definition: third.py:92
Parse command-line arguments.
Definition: command-line.h:205
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
tuple wifiApNode
Definition: third.py:83
void LogComponentEnableAll(enum LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:393
OFDM PHY for the 5 GHz band (Clause 17)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void SetMobilityModel(std::string type, 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(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
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())
tuple ssid
Definition: third.py:93
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:139
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...
virtual void SetType(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(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue(), std::string n10="", const AttributeValue &v10=EmptyAttributeValue())
Helper class used to assign positions and mobility models to nodes.
static SpectrumChannelHelper Default()
Setup a default SpectrumChannel.
All prefixes.
Definition: log.h:118
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:498
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
AttributeValue implementation for Ssid.
Definition: ssid.h:110
void Add(Vector v)
Add a position to the list of positions.
void SetChannel(Ptr< SpectrumChannel > channel)
Set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper...
Print everything.
Definition: log.h:112
void Parse(int argc, char *argv[])
Parse the program arguments.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1023
tuple wifi
Definition: third.py:89
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Setup a SpectrumChannel.
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
bool verbose
Make it easy to create and manage PHY objects for the spectrum model.