A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
32using namespace ns3;
33
34/// PsrExperiment
36{
37 public:
38 /// Input structure
39 struct Input
40 {
41 Input();
42 double distance; ///< distance
43 std::string txMode; ///< transmit mode
44 uint8_t txPowerLevel; ///< transmit power level
45 uint32_t packetSize; ///< packet size
46 uint32_t nPackets; ///< number of packets
47 };
48
49 /// Output structure
50 struct Output
51 {
52 uint32_t received; ///< received
53 };
54
56
57 /**
58 * Run function
59 * \param input the PSR experiment
60 * \returns the PSR experiment output
61 */
63
64 private:
65 /// Send function
66 void Send();
67 /**
68 * Send receive function
69 * \param psdu the PSDU
70 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
71 * \param txVector the wifi transmit vector
72 * \param statusPerMpdu reception status per MPDU
73 */
75 RxSignalInfo rxSignalInfo,
76 WifiTxVector txVector,
77 std::vector<bool> statusPerMpdu);
78 Ptr<WifiPhy> m_tx; ///< transmit
79 Input m_input; ///< input
80 Output m_output; ///< output
81};
82
83void
85{
86 Ptr<WifiPsdu> psdu = Create<WifiPsdu>(Create<Packet>(m_input.packetSize), WifiMacHeader());
88 WifiTxVector txVector;
90 txVector.SetMode(mode);
92 m_tx->Send(psdu, txVector);
93}
94
95void
97 RxSignalInfo rxSignalInfo,
98 WifiTxVector txVector,
99 std::vector<bool> statusPerMpdu)
100{
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
143 tx->ConfigureStandard(WIFI_STANDARD_80211a);
144 rx->ConfigureStandard(WIFI_STANDARD_80211a);
145
146 rx->SetReceiveOkCallback(MakeCallback(&PsrExperiment::Receive, this));
147
148 for (uint32_t i = 0; i < m_input.nPackets; ++i)
149 {
151 }
152 m_tx = tx;
155 return m_output;
156}
157
158/// CollisionExperiment
160{
161 public:
162 /// Input structure
163 struct Input
164 {
165 Input();
166 Time interval; ///< interval
167 double xA; ///< x A
168 double xB; ///< x B
169 std::string txModeA; ///< transmit mode A
170 std::string txModeB; ///< transmit mode B
171 uint8_t txPowerLevelA; ///< transmit power level A
172 uint8_t txPowerLevelB; ///< transmit power level B
173 uint32_t packetSizeA; ///< packet size A
174 uint32_t packetSizeB; ///< packet size B
175 uint32_t nPackets; ///< number of packets
176 };
177
178 /// Output structure
179 struct Output
180 {
181 uint32_t receivedA; ///< received A
182 uint32_t receivedB; ///< received B
183 };
184
186
187 /**
188 * Run function
189 * \param input the collision experiment data
190 * \returns the experiment output
191 */
193
194 private:
195 /// Send A function
196 void SendA() const;
197 /// Send B function
198 void SendB() const;
199 /**
200 * Receive function
201 * \param psdu the PSDU
202 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
203 * \param txVector the wifi transmit vector
204 * \param statusPerMpdu reception status per MPDU
205 */
206 void Receive(Ptr<const WifiPsdu> psdu,
207 RxSignalInfo rxSignalInfo,
208 WifiTxVector txVector,
209 std::vector<bool> statusPerMpdu);
210 Ptr<WifiPhy> m_txA; ///< transmit A
211 Ptr<WifiPhy> m_txB; ///< transmit B
212 uint32_t m_flowIdA; ///< flow ID A
213 uint32_t m_flowIdB; ///< flow ID B
214 Input m_input; ///< input
215 Output m_output; ///< output
216};
217
218void
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
230void
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
242void
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{
285 m_input = input;
286
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
317 txA->ConfigureStandard(WIFI_STANDARD_80211a);
318 txB->ConfigureStandard(WIFI_STANDARD_80211a);
319 rx->ConfigureStandard(WIFI_STANDARD_80211a);
320
321 rx->SetReceiveOkCallback(MakeCallback(&CollisionExperiment::Receive, this));
322
323 for (uint32_t i = 0; i < m_input.nPackets; ++i)
324 {
326 }
327 for (uint32_t i = 0; i < m_input.nPackets; ++i)
328 {
330 }
331 m_txA = txA;
332 m_txB = txB;
335 return m_output;
336}
337
338static void
339PrintPsr(int argc, char* argv[])
340{
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
355 output = experiment.Run(input);
356
357 double psr = output.received;
358 psr /= input.nPackets;
359
360 std::cout << psr << std::endl;
361}
362
363double
365{
366 double psr = output.received;
367 psr /= input.nPackets;
368 return psr;
369}
370
371static void
372PrintPsrVsDistance(int argc, char* argv[])
373{
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;
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
426static void
427PrintSizeVsRange(int argc, char* argv[])
428{
429 double targetPsr = 0.05;
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;
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
466static void
467PrintPsrVsCollisionInterval(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
499int
500main(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
Introspection did not find any typical Config paths.
Definition: flow-id-tag.h:28
uint32_t GetFlowId() const
Gets the flow id for the tag.
Definition: flow-id-tag.cc:95
static uint32_t AllocateFlowId()
Uses a static variable to generate sequential flow id.
Definition: flow-id-tag.cc:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
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 Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1741
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 experiment(std::string queue_disc_type)
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
@ 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:706
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.