A Discrete-Event Network Simulator
API
wifi-phy-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 
20 #include "ns3/command-line.h"
21 #include "ns3/constant-position-mobility-model.h"
22 #include "ns3/flow-id-tag.h"
23 #include "ns3/nist-error-rate-model.h"
24 #include "ns3/packet.h"
25 #include "ns3/propagation-delay-model.h"
26 #include "ns3/propagation-loss-model.h"
27 #include "ns3/simulator.h"
28 #include "ns3/wifi-psdu.h"
29 #include "ns3/yans-wifi-channel.h"
30 #include "ns3/yans-wifi-phy.h"
31 
32 using namespace ns3;
33 
36 {
37  public:
39  struct Input
40  {
41  Input();
42  double distance;
43  std::string txMode;
44  uint8_t txPowerLevel;
45  uint32_t packetSize;
46  uint32_t nPackets;
47  };
48 
50  struct Output
51  {
52  uint32_t received;
53  };
54 
55  PsrExperiment();
56 
63 
64  private:
66  void Send();
74  void Receive(Ptr<const WifiPsdu> psdu,
75  RxSignalInfo rxSignalInfo,
76  WifiTxVector txVector,
77  std::vector<bool> statusPerMpdu);
81 };
82 
83 void
85 {
86  Ptr<WifiPsdu> psdu = Create<WifiPsdu>(Create<Packet>(m_input.packetSize), WifiMacHeader());
87  WifiMode mode = WifiMode(m_input.txMode);
88  WifiTxVector txVector;
89  txVector.SetTxPowerLevel(m_input.txPowerLevel);
90  txVector.SetMode(mode);
92  m_tx->Send(psdu, txVector);
93 }
94 
95 void
97  RxSignalInfo rxSignalInfo,
98  WifiTxVector txVector,
99  std::vector<bool> statusPerMpdu)
100 {
101  m_output.received++;
102 }
103 
105 {
106 }
107 
109  : distance(5.0),
110  txMode("OfdmRate6Mbps"),
111  txPowerLevel(0),
112  packetSize(2304),
113  nPackets(400)
114 {
115 }
116 
119 {
120  m_output.received = 0;
121  m_input = input;
122 
123  Ptr<MobilityModel> posTx = CreateObject<ConstantPositionMobilityModel>();
124  posTx->SetPosition(Vector(0.0, 0.0, 0.0));
125  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel>();
126  posRx->SetPosition(Vector(m_input.distance, 0.0, 0.0));
127 
128  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
129  channel->SetPropagationDelayModel(CreateObject<ConstantSpeedPropagationDelayModel>());
130  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel>();
131  channel->SetPropagationLossModel(log);
132 
133  Ptr<YansWifiPhy> tx = CreateObject<YansWifiPhy>();
134  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy>();
135  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
136  tx->SetErrorRateModel(error);
137  rx->SetErrorRateModel(error);
138  tx->SetChannel(channel);
139  rx->SetChannel(channel);
140  tx->SetMobility(posTx);
141  rx->SetMobility(posRx);
142 
145 
147 
148  for (uint32_t i = 0; i < m_input.nPackets; ++i)
149  {
150  Simulator::Schedule(Seconds(i), &PsrExperiment::Send, this);
151  }
152  m_tx = tx;
153  Simulator::Run();
154  Simulator::Destroy();
155  return m_output;
156 }
157 
160 {
161  public:
163  struct Input
164  {
165  Input();
167  double xA;
168  double xB;
169  std::string txModeA;
170  std::string txModeB;
171  uint8_t txPowerLevelA;
172  uint8_t txPowerLevelB;
173  uint32_t packetSizeA;
174  uint32_t packetSizeB;
175  uint32_t nPackets;
176  };
177 
179  struct Output
180  {
181  uint32_t receivedA;
182  uint32_t receivedB;
183  };
184 
186 
193 
194  private:
196  void SendA() const;
198  void SendB() const;
206  void Receive(Ptr<const WifiPsdu> psdu,
207  RxSignalInfo rxSignalInfo,
208  WifiTxVector txVector,
209  std::vector<bool> statusPerMpdu);
212  uint32_t m_flowIdA;
213  uint32_t m_flowIdB;
216 };
217 
218 void
220 {
221  Ptr<WifiPsdu> psdu = Create<WifiPsdu>(Create<Packet>(m_input.packetSizeA), WifiMacHeader());
222  (*psdu->begin())->GetPacket()->AddByteTag(FlowIdTag(m_flowIdA));
223  WifiTxVector txVector;
224  txVector.SetTxPowerLevel(m_input.txPowerLevelA);
225  txVector.SetMode(WifiMode(m_input.txModeA));
227  m_txA->Send(psdu, txVector);
228 }
229 
230 void
232 {
233  Ptr<WifiPsdu> psdu = Create<WifiPsdu>(Create<Packet>(m_input.packetSizeB), WifiMacHeader());
234  (*psdu->begin())->GetPacket()->AddByteTag(FlowIdTag(m_flowIdB));
235  WifiTxVector txVector;
236  txVector.SetTxPowerLevel(m_input.txPowerLevelB);
237  txVector.SetMode(WifiMode(m_input.txModeB));
239  m_txB->Send(psdu, txVector);
240 }
241 
242 void
244  RxSignalInfo rxSignalInfo,
245  WifiTxVector txVector,
246  std::vector<bool> statusPerMpdu)
247 {
248  FlowIdTag tag;
249  if ((*psdu->begin())->GetPacket()->FindFirstMatchingByteTag(tag))
250  {
251  if (tag.GetFlowId() == m_flowIdA)
252  {
253  m_output.receivedA++;
254  }
255  else if (tag.GetFlowId() == m_flowIdB)
256  {
257  m_output.receivedB++;
258  }
259  }
260 }
261 
263 {
264 }
265 
267  : interval(MicroSeconds(0)),
268  xA(-5),
269  xB(5),
270  txModeA("OfdmRate6Mbps"),
271  txModeB("OfdmRate6Mbps"),
272  txPowerLevelA(0),
273  txPowerLevelB(0),
274  packetSizeA(2304),
275  packetSizeB(2304),
276  nPackets(400)
277 {
278 }
279 
282 {
283  m_output.receivedA = 0;
284  m_output.receivedB = 0;
285  m_input = input;
286 
287  m_flowIdA = FlowIdTag::AllocateFlowId();
288  m_flowIdB = FlowIdTag::AllocateFlowId();
289 
290  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel>();
291  channel->SetPropagationDelayModel(CreateObject<ConstantSpeedPropagationDelayModel>());
292  Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel>();
293  channel->SetPropagationLossModel(log);
294 
295  Ptr<MobilityModel> posTxA = CreateObject<ConstantPositionMobilityModel>();
296  posTxA->SetPosition(Vector(input.xA, 0.0, 0.0));
297  Ptr<MobilityModel> posTxB = CreateObject<ConstantPositionMobilityModel>();
298  posTxB->SetPosition(Vector(input.xB, 0.0, 0.0));
299  Ptr<MobilityModel> posRx = CreateObject<ConstantPositionMobilityModel>();
300  posRx->SetPosition(Vector(0, 0.0, 0.0));
301 
302  Ptr<YansWifiPhy> txA = CreateObject<YansWifiPhy>();
303  Ptr<YansWifiPhy> txB = CreateObject<YansWifiPhy>();
304  Ptr<YansWifiPhy> rx = CreateObject<YansWifiPhy>();
305 
306  Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel>();
307  txA->SetErrorRateModel(error);
308  txB->SetErrorRateModel(error);
309  rx->SetErrorRateModel(error);
310  txA->SetChannel(channel);
311  txB->SetChannel(channel);
312  rx->SetChannel(channel);
313  txA->SetMobility(posTxA);
314  txB->SetMobility(posTxB);
315  rx->SetMobility(posRx);
316 
320 
322 
323  for (uint32_t i = 0; i < m_input.nPackets; ++i)
324  {
325  Simulator::Schedule(Seconds(i), &CollisionExperiment::SendA, this);
326  }
327  for (uint32_t i = 0; i < m_input.nPackets; ++i)
328  {
329  Simulator::Schedule(Seconds(i) + m_input.interval, &CollisionExperiment::SendB, this);
330  }
331  m_txA = txA;
332  m_txB = txB;
333  Simulator::Run();
334  Simulator::Destroy();
335  return m_output;
336 }
337 
338 static void
339 PrintPsr(int argc, char* argv[])
340 {
342  PsrExperiment::Input input;
343 
344  CommandLine cmd(__FILE__);
345  cmd.AddValue("Distance", "The distance between two phys", input.distance);
346  cmd.AddValue("PacketSize", "The size of each packet sent", input.packetSize);
347  cmd.AddValue("TxMode", "The mode to use to send each packet", input.txMode);
348  cmd.AddValue("NPackets", "The number of packets to send", input.nPackets);
349  cmd.AddValue("TxPowerLevel",
350  "The power level index to use to send each packet",
351  input.txPowerLevel);
352  cmd.Parse(argc, argv);
353 
354  PsrExperiment::Output output;
355  output = experiment.Run(input);
356 
357  double psr = output.received;
358  psr /= input.nPackets;
359 
360  std::cout << psr << std::endl;
361 }
362 
363 double
365 {
366  double psr = output.received;
367  psr /= input.nPackets;
368  return psr;
369 }
370 
371 static void
372 PrintPsrVsDistance(int argc, char* argv[])
373 {
374  PsrExperiment::Input input;
375  CommandLine cmd(__FILE__);
376  cmd.AddValue("TxPowerLevel",
377  "The power level index to use to send each packet",
378  input.txPowerLevel);
379  cmd.AddValue("TxMode", "The mode to use to send each packet", input.txMode);
380  cmd.AddValue("NPackets", "The number of packets to send", input.nPackets);
381  cmd.AddValue("PacketSize", "The size of each packet sent", input.packetSize);
382  cmd.Parse(argc, argv);
383 
384  for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
385  {
386  std::cout << input.distance;
388  PsrExperiment::Output output;
389 
390  input.txMode = "OfdmRate6Mbps";
391  output = experiment.Run(input);
392  std::cout << " " << CalcPsr(output, input);
393 
394  input.txMode = "OfdmRate9Mbps";
395  output = experiment.Run(input);
396  std::cout << " " << CalcPsr(output, input);
397 
398  input.txMode = "OfdmRate12Mbps";
399  output = experiment.Run(input);
400  std::cout << " " << CalcPsr(output, input);
401 
402  input.txMode = "OfdmRate18Mbps";
403  output = experiment.Run(input);
404  std::cout << " " << CalcPsr(output, input);
405 
406  input.txMode = "OfdmRate24Mbps";
407  output = experiment.Run(input);
408  std::cout << " " << CalcPsr(output, input);
409 
410  input.txMode = "OfdmRate36Mbps";
411  output = experiment.Run(input);
412  std::cout << " " << CalcPsr(output, input);
413 
414  input.txMode = "OfdmRate48Mbps";
415  output = experiment.Run(input);
416  std::cout << " " << CalcPsr(output, input);
417 
418  input.txMode = "OfdmRate54Mbps";
419  output = experiment.Run(input);
420  std::cout << " " << CalcPsr(output, input);
421 
422  std::cout << std::endl;
423  }
424 }
425 
426 static void
427 PrintSizeVsRange(int argc, char* argv[])
428 {
429  double targetPsr = 0.05;
430  PsrExperiment::Input input;
431  CommandLine cmd(__FILE__);
432  cmd.AddValue("TxPowerLevel",
433  "The power level index to use to send each packet",
434  input.txPowerLevel);
435  cmd.AddValue("TxMode", "The mode to use to send each packet", input.txMode);
436  cmd.AddValue("NPackets", "The number of packets to send", input.nPackets);
437  cmd.AddValue("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
438  cmd.Parse(argc, argv);
439 
440  for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
441  {
442  double precision = 0.1;
443  double low = 1.0;
444  double high = 200.0;
445  while (high - low > precision)
446  {
447  double middle = low + (high - low) / 2;
448  PsrExperiment::Output output;
450  input.distance = middle;
451  output = experiment.Run(input);
452  double psr = CalcPsr(output, input);
453  if (psr >= targetPsr)
454  {
455  low = middle;
456  }
457  else
458  {
459  high = middle;
460  }
461  }
462  std::cout << input.packetSize << " " << input.distance << std::endl;
463  }
464 }
465 
466 static void
467 PrintPsrVsCollisionInterval(int argc, char* argv[])
468 {
470  input.nPackets = 100;
471  CommandLine cmd(__FILE__);
472  cmd.AddValue("NPackets", "The number of packets to send for each transmitter", input.nPackets);
473  cmd.AddValue("xA", "the position of transmitter A", input.xA);
474  cmd.AddValue("xB", "the position of transmitter B", input.xB);
475  cmd.Parse(argc, argv);
476 
477  for (uint32_t i = 0; i < 100; i += 1)
478  {
481  input.interval = MicroSeconds(i);
482  output = experiment.Run(input);
483  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
484  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
485  std::cout << i << " " << perA << " " << perB << std::endl;
486  }
487  for (uint32_t i = 100; i < 4000; i += 50)
488  {
491  input.interval = MicroSeconds(i);
492  output = experiment.Run(input);
493  double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
494  double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
495  std::cout << i << " " << perA << " " << perB << std::endl;
496  }
497 }
498 
499 int
500 main(int argc, char* argv[])
501 {
502  if (argc <= 1)
503  {
504  std::cout << "Available experiments: "
505  << "Psr "
506  << "SizeVsRange "
507  << "PsrVsDistance "
508  << "PsrVsCollisionInterval " << std::endl;
509  return 0;
510  }
511  std::string type = argv[1];
512  argc--;
513  argv[1] = argv[0];
514  argv++;
515  if (type == "Psr")
516  {
517  PrintPsr(argc, argv);
518  }
519  else if (type == "SizeVsRange")
520  {
521  PrintSizeVsRange(argc, argv);
522  }
523  else if (type == "PsrVsDistance")
524  {
525  PrintPsrVsDistance(argc, argv);
526  }
527  else if (type == "PsrVsCollisionInterval")
528  {
529  PrintPsrVsCollisionInterval(argc, argv);
530  }
531  else
532  {
533  std::cout << "Wrong arguments!" << std::endl;
534  }
535 
536  return 0;
537 }
CollisionExperiment.
uint32_t m_flowIdB
flow ID B
void SendA() const
Send A function.
void SendB() const
Send B function.
CollisionExperiment::Output Run(CollisionExperiment::Input input)
Run function.
Ptr< WifiPhy > m_txB
transmit B
Output m_output
output
Ptr< WifiPhy > m_txA
transmit A
uint32_t m_flowIdA
flow ID A
void Receive(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Receive function.
PsrExperiment.
Ptr< WifiPhy > m_tx
transmit
Input m_input
input
PsrExperiment::Output Run(PsrExperiment::Input input)
Run function.
void Receive(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector< bool > statusPerMpdu)
Send receive function.
Output m_output
output
void Send()
Send function.
Parse command-line arguments.
Definition: command-line.h:232
uint32_t GetFlowId() const
Gets the flow id for the tag.
Definition: flow-id-tag.cc:95
void SetPosition(const Vector &position)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Implements the IEEE 802.11 MAC header.
represent a single transmission mode
Definition: wifi-mode.h:51
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:639
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:961
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:619
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:449
std::vector< Ptr< WifiMpdu > >::const_iterator begin() const
Return a const iterator to the first MPDU.
Definition: wifi-psdu.cc:333
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 SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
void SetChannel(const Ptr< YansWifiChannel > channel)
Set the YansWifiChannel this YansWifiPhy is to be connected to.
void experiment(std::string queue_disc_type)
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
Definition: fd-emu-send.cc:54
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
@ WIFI_STANDARD_80211a
@ WIFI_PREAMBLE_LONG
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:704
cmd
Definition: second.py:40
channel
Definition: third.py:88
uint32_t nPackets
number of packets
uint8_t txPowerLevelB
transmit power level B
uint32_t packetSizeA
packet size A
std::string txModeA
transmit mode A
uint8_t txPowerLevelA
transmit power level A
uint32_t packetSizeB
packet size B
std::string txModeB
transmit mode B
uint32_t receivedA
received A
uint32_t receivedB
received B
Input structure.
uint32_t nPackets
number of packets
std::string txMode
transmit mode
double distance
distance
uint8_t txPowerLevel
transmit power level
uint32_t packetSize
packet size
Output structure.
uint32_t received
received
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:69
static void PrintPsr(int argc, char *argv[])
double CalcPsr(PsrExperiment::Output output, PsrExperiment::Input input)
static void PrintPsrVsCollisionInterval(int argc, char *argv[])
static void PrintPsrVsDistance(int argc, char *argv[])
static void PrintSizeVsRange(int argc, char *argv[])
static const uint32_t packetSize
Packet size generated at the AP.