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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "ns3/command-line.h"
10#include "ns3/constant-position-mobility-model.h"
11#include "ns3/flow-id-tag.h"
12#include "ns3/nist-error-rate-model.h"
13#include "ns3/packet.h"
14#include "ns3/propagation-delay-model.h"
15#include "ns3/propagation-loss-model.h"
16#include "ns3/simulator.h"
17#include "ns3/wifi-psdu.h"
18#include "ns3/yans-wifi-channel.h"
19#include "ns3/yans-wifi-phy.h"
20
21using namespace ns3;
22
23/// PsrExperiment
25{
26 public:
27 /// Input structure
28 struct Input
29 {
30 Input();
31 meter_u distance; ///< distance
32 std::string txMode; ///< transmit mode
33 uint8_t txPowerLevel; ///< transmit power level
34 uint32_t packetSize; ///< packet size
35 uint32_t nPackets; ///< number of packets
36 };
37
38 /// Output structure
39 struct Output
40 {
41 uint32_t received; ///< received
42 };
43
45
46 /**
47 * Run function
48 * \param input the PSR experiment
49 * \returns the PSR experiment output
50 */
52
53 private:
54 /// Send function
55 void Send();
56 /**
57 * Send receive function
58 * \param psdu the PSDU
59 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
60 * \param txVector the wifi transmit vector
61 * \param statusPerMpdu reception status per MPDU
62 */
64 RxSignalInfo rxSignalInfo,
65 WifiTxVector txVector,
66 std::vector<bool> statusPerMpdu);
67 Ptr<WifiPhy> m_tx; ///< transmit
68 Input m_input; ///< input
69 Output m_output; ///< output
70};
71
72void
83
84void
86 RxSignalInfo rxSignalInfo,
87 WifiTxVector txVector,
88 std::vector<bool> statusPerMpdu)
89{
91}
92
96
98 : distance(5.0),
99 txMode("OfdmRate6Mbps"),
100 txPowerLevel(0),
101 packetSize(2304),
102 nPackets(400)
103{
104}
105
108{
109 m_output.received = 0;
110 m_input = input;
111
113 posTx->SetPosition(Vector(0.0, 0.0, 0.0));
115 posRx->SetPosition(Vector(m_input.distance, 0.0, 0.0));
116
118 channel->SetPropagationDelayModel(CreateObject<ConstantSpeedPropagationDelayModel>());
120 channel->SetPropagationLossModel(log);
121
125 tx->SetErrorRateModel(error);
126 rx->SetErrorRateModel(error);
127 tx->SetChannel(channel);
128 rx->SetChannel(channel);
129 tx->SetMobility(posTx);
130 rx->SetMobility(posRx);
131
132 tx->ConfigureStandard(WIFI_STANDARD_80211a);
133 rx->ConfigureStandard(WIFI_STANDARD_80211a);
134
135 rx->SetReceiveOkCallback(MakeCallback(&PsrExperiment::Receive, this));
136
137 for (uint32_t i = 0; i < m_input.nPackets; ++i)
138 {
140 }
141 m_tx = tx;
144 return m_output;
145}
146
147/// CollisionExperiment
149{
150 public:
151 /// Input structure
152 struct Input
153 {
154 Input();
155 Time interval; ///< interval
156 double xA; ///< x A
157 double xB; ///< x B
158 std::string txModeA; ///< transmit mode A
159 std::string txModeB; ///< transmit mode B
160 uint8_t txPowerLevelA; ///< transmit power level A
161 uint8_t txPowerLevelB; ///< transmit power level B
162 uint32_t packetSizeA; ///< packet size A
163 uint32_t packetSizeB; ///< packet size B
164 uint32_t nPackets; ///< number of packets
165 };
166
167 /// Output structure
168 struct Output
169 {
170 uint32_t receivedA; ///< received A
171 uint32_t receivedB; ///< received B
172 };
173
175
176 /**
177 * Run function
178 * \param input the collision experiment data
179 * \returns the experiment output
180 */
182
183 private:
184 /// Send A function
185 void SendA() const;
186 /// Send B function
187 void SendB() const;
188 /**
189 * Receive function
190 * \param psdu the PSDU
191 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo)
192 * \param txVector the wifi transmit vector
193 * \param statusPerMpdu reception status per MPDU
194 */
195 void Receive(Ptr<const WifiPsdu> psdu,
196 RxSignalInfo rxSignalInfo,
197 WifiTxVector txVector,
198 std::vector<bool> statusPerMpdu);
199 Ptr<WifiPhy> m_txA; ///< transmit A
200 Ptr<WifiPhy> m_txB; ///< transmit B
201 uint32_t m_flowIdA; ///< flow ID A
202 uint32_t m_flowIdB; ///< flow ID B
203 Input m_input; ///< input
204 Output m_output; ///< output
205};
206
207void
209{
211 (*psdu->begin())->GetPacket()->AddByteTag(FlowIdTag(m_flowIdA));
212 WifiTxVector txVector;
213 txVector.SetTxPowerLevel(m_input.txPowerLevelA);
214 txVector.SetMode(WifiMode(m_input.txModeA));
216 m_txA->Send(psdu, txVector);
217}
218
219void
221{
223 (*psdu->begin())->GetPacket()->AddByteTag(FlowIdTag(m_flowIdB));
224 WifiTxVector txVector;
225 txVector.SetTxPowerLevel(m_input.txPowerLevelB);
226 txVector.SetMode(WifiMode(m_input.txModeB));
228 m_txB->Send(psdu, txVector);
229}
230
231void
233 RxSignalInfo rxSignalInfo,
234 WifiTxVector txVector,
235 std::vector<bool> statusPerMpdu)
236{
237 FlowIdTag tag;
238 if ((*psdu->begin())->GetPacket()->FindFirstMatchingByteTag(tag))
239 {
240 if (tag.GetFlowId() == m_flowIdA)
241 {
242 m_output.receivedA++;
243 }
244 else if (tag.GetFlowId() == m_flowIdB)
245 {
246 m_output.receivedB++;
247 }
248 }
249}
250
254
256 : interval(MicroSeconds(0)),
257 xA(-5),
258 xB(5),
259 txModeA("OfdmRate6Mbps"),
260 txModeB("OfdmRate6Mbps"),
261 txPowerLevelA(0),
262 txPowerLevelB(0),
263 packetSizeA(2304),
264 packetSizeB(2304),
265 nPackets(400)
266{
267}
268
271{
274 m_input = input;
275
278
280 channel->SetPropagationDelayModel(CreateObject<ConstantSpeedPropagationDelayModel>());
282 channel->SetPropagationLossModel(log);
283
285 posTxA->SetPosition(Vector(input.xA, 0.0, 0.0));
287 posTxB->SetPosition(Vector(input.xB, 0.0, 0.0));
289 posRx->SetPosition(Vector(0, 0.0, 0.0));
290
294
296 txA->SetErrorRateModel(error);
297 txB->SetErrorRateModel(error);
298 rx->SetErrorRateModel(error);
299 txA->SetChannel(channel);
300 txB->SetChannel(channel);
301 rx->SetChannel(channel);
302 txA->SetMobility(posTxA);
303 txB->SetMobility(posTxB);
304 rx->SetMobility(posRx);
305
306 txA->ConfigureStandard(WIFI_STANDARD_80211a);
307 txB->ConfigureStandard(WIFI_STANDARD_80211a);
308 rx->ConfigureStandard(WIFI_STANDARD_80211a);
309
310 rx->SetReceiveOkCallback(MakeCallback(&CollisionExperiment::Receive, this));
311
312 for (uint32_t i = 0; i < m_input.nPackets; ++i)
313 {
315 }
316 for (uint32_t i = 0; i < m_input.nPackets; ++i)
317 {
319 }
320 m_txA = txA;
321 m_txB = txB;
324 return m_output;
325}
326
327static void
328PrintPsr(int argc, char* argv[])
329{
332
333 CommandLine cmd(__FILE__);
334 cmd.AddValue("Distance", "The distance between two phys", input.distance);
335 cmd.AddValue("PacketSize", "The size of each packet sent", input.packetSize);
336 cmd.AddValue("TxMode", "The mode to use to send each packet", input.txMode);
337 cmd.AddValue("NPackets", "The number of packets to send", input.nPackets);
338 cmd.AddValue("TxPowerLevel",
339 "The power level index to use to send each packet",
340 input.txPowerLevel);
341 cmd.Parse(argc, argv);
342
344 output = experiment.Run(input);
345
346 double psr = output.received;
347 psr /= input.nPackets;
348
349 std::cout << psr << std::endl;
350}
351
352double
354{
355 double psr = output.received;
356 psr /= input.nPackets;
357 return psr;
358}
359
360static void
361PrintPsrVsDistance(int argc, char* argv[])
362{
364 CommandLine cmd(__FILE__);
365 cmd.AddValue("TxPowerLevel",
366 "The power level index to use to send each packet",
367 input.txPowerLevel);
368 cmd.AddValue("TxMode", "The mode to use to send each packet", input.txMode);
369 cmd.AddValue("NPackets", "The number of packets to send", input.nPackets);
370 cmd.AddValue("PacketSize", "The size of each packet sent", input.packetSize);
371 cmd.Parse(argc, argv);
372
373 for (input.distance = 1.0; input.distance < 165; input.distance += 2.0)
374 {
375 std::cout << input.distance;
378
379 input.txMode = "OfdmRate6Mbps";
380 output = experiment.Run(input);
381 std::cout << " " << CalcPsr(output, input);
382
383 input.txMode = "OfdmRate9Mbps";
384 output = experiment.Run(input);
385 std::cout << " " << CalcPsr(output, input);
386
387 input.txMode = "OfdmRate12Mbps";
388 output = experiment.Run(input);
389 std::cout << " " << CalcPsr(output, input);
390
391 input.txMode = "OfdmRate18Mbps";
392 output = experiment.Run(input);
393 std::cout << " " << CalcPsr(output, input);
394
395 input.txMode = "OfdmRate24Mbps";
396 output = experiment.Run(input);
397 std::cout << " " << CalcPsr(output, input);
398
399 input.txMode = "OfdmRate36Mbps";
400 output = experiment.Run(input);
401 std::cout << " " << CalcPsr(output, input);
402
403 input.txMode = "OfdmRate48Mbps";
404 output = experiment.Run(input);
405 std::cout << " " << CalcPsr(output, input);
406
407 input.txMode = "OfdmRate54Mbps";
408 output = experiment.Run(input);
409 std::cout << " " << CalcPsr(output, input);
410
411 std::cout << std::endl;
412 }
413}
414
415static void
416PrintSizeVsRange(int argc, char* argv[])
417{
418 double targetPsr = 0.05;
420 CommandLine cmd(__FILE__);
421 cmd.AddValue("TxPowerLevel",
422 "The power level index to use to send each packet",
423 input.txPowerLevel);
424 cmd.AddValue("TxMode", "The mode to use to send each packet", input.txMode);
425 cmd.AddValue("NPackets", "The number of packets to send", input.nPackets);
426 cmd.AddValue("TargetPsr", "The psr needed to assume that we are within range", targetPsr);
427 cmd.Parse(argc, argv);
428
429 for (input.packetSize = 10; input.packetSize < 3000; input.packetSize += 40)
430 {
431 double precision = 0.1;
432 double low = 1.0;
433 double high = 200.0;
434 while (high - low > precision)
435 {
436 double middle = low + (high - low) / 2;
439 input.distance = middle;
440 output = experiment.Run(input);
441 double psr = CalcPsr(output, input);
442 if (psr >= targetPsr)
443 {
444 low = middle;
445 }
446 else
447 {
448 high = middle;
449 }
450 }
451 std::cout << input.packetSize << " " << input.distance << std::endl;
452 }
453}
454
455static void
456PrintPsrVsCollisionInterval(int argc, char* argv[])
457{
459 input.nPackets = 100;
460 CommandLine cmd(__FILE__);
461 cmd.AddValue("NPackets", "The number of packets to send for each transmitter", input.nPackets);
462 cmd.AddValue("xA", "the position of transmitter A", input.xA);
463 cmd.AddValue("xB", "the position of transmitter B", input.xB);
464 cmd.Parse(argc, argv);
465
466 for (uint32_t i = 0; i < 100; i += 1)
467 {
470 input.interval = MicroSeconds(i);
471 output = experiment.Run(input);
472 double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
473 double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
474 std::cout << i << " " << perA << " " << perB << std::endl;
475 }
476 for (uint32_t i = 100; i < 4000; i += 50)
477 {
480 input.interval = MicroSeconds(i);
481 output = experiment.Run(input);
482 double perA = (output.receivedA + 0.0) / (input.nPackets + 0.0);
483 double perB = (output.receivedB + 0.0) / (input.nPackets + 0.0);
484 std::cout << i << " " << perA << " " << perB << std::endl;
485 }
486}
487
488int
489main(int argc, char* argv[])
490{
491 if (argc <= 1)
492 {
493 std::cout << "Available experiments: "
494 << "Psr "
495 << "SizeVsRange "
496 << "PsrVsDistance "
497 << "PsrVsCollisionInterval " << std::endl;
498 return 0;
499 }
500 std::string type = argv[1];
501 argc--;
502 argv[1] = argv[0];
503 argv++;
504 if (type == "Psr")
505 {
506 PrintPsr(argc, argv);
507 }
508 else if (type == "SizeVsRange")
509 {
510 PrintSizeVsRange(argc, argv);
511 }
512 else if (type == "PsrVsDistance")
513 {
514 PrintPsrVsDistance(argc, argv);
515 }
516 else if (type == "PsrVsCollisionInterval")
517 {
518 PrintPsrVsCollisionInterval(argc, argv);
519 }
520 else
521 {
522 std::cout << "Wrong arguments!" << std::endl;
523 }
524
525 return 0;
526}
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
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.
uint32_t GetFlowId() const
Gets the flow id for the tag.
static uint32_t AllocateFlowId()
Uses a static variable to generate sequential flow id.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Implements the IEEE 802.11 MAC header.
represent a single transmission mode
Definition wifi-mode.h:40
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:1792
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)
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
@ 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:684
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
meter_u 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 wifi-types.h:72
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.