A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-bianchi.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012 The Boeing Company
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Gary Pei <guangyu.pei@boeing.com>
7 *
8 * Updated by Tom Henderson, Rohan Patidar, Hao Yin and Sébastien Deronne
9 */
10
11// This program conducts a Bianchi analysis of a wifi network.
12// Bianchi analysis involves saturating the network and observing how
13// the maximum achievable throughput is governed by the DCF or ECDA
14// channel access mechanisms. This program offers many configurable
15// options, traces, and a validation option; the main output is a Gnuplot
16// plot file plotting throughput vs. number of nodes.
17
18#include "ns3/ampdu-subframe-header.h"
19#include "ns3/application-container.h"
20#include "ns3/boolean.h"
21#include "ns3/command-line.h"
22#include "ns3/config.h"
23#include "ns3/double.h"
24#include "ns3/gnuplot.h"
25#include "ns3/integer.h"
26#include "ns3/log.h"
27#include "ns3/mobility-helper.h"
28#include "ns3/node-list.h"
29#include "ns3/packet-socket-client.h"
30#include "ns3/packet-socket-helper.h"
31#include "ns3/packet-socket-server.h"
32#include "ns3/propagation-delay-model.h"
33#include "ns3/propagation-loss-model.h"
34#include "ns3/queue-size.h"
35#include "ns3/rng-seed-manager.h"
36#include "ns3/ssid.h"
37#include "ns3/string.h"
38#include "ns3/uinteger.h"
39#include "ns3/wifi-mac-header.h"
40#include "ns3/wifi-mac.h"
41#include "ns3/wifi-net-device.h"
42#include "ns3/wifi-phy-rx-trace-helper.h"
43#include "ns3/wifi-tx-stats-helper.h"
44#include "ns3/yans-wifi-helper.h"
45
46#include <fstream>
47#include <iomanip>
48#include <numbers>
49#include <vector>
50
51/**
52 * @file
53 * Example comparing ns-3 to the Bianchi model.
54 *
55 * See the Wi-Fi Module documentation in the Models chapter.
56 */
57
58NS_LOG_COMPONENT_DEFINE("WifiBianchi");
59
60using namespace ns3;
61
62/** Unnamed namespace, to disambiguate class Experiment. */
63namespace
64{
65
66std::ofstream cwTraceFile; ///< File that traces CW over time
67std::ofstream backoffTraceFile; ///< File that traces backoff over time
68std::ofstream phyTxTraceFile; ///< File that traces PHY transmissions over time
69std::ofstream macTxTraceFile; ///< File that traces MAC transmissions over time
70std::ofstream macRxTraceFile; ///< File that traces MAC receptions over time
71std::ofstream
72 socketSendTraceFile; ///< File that traces packets transmitted by the application over time
73
74std::map<Mac48Address, uint64_t> packetsReceived; ///< Map that stores the total packets received
75 ///< per STA (and addressed to that STA)
76std::map<Mac48Address, uint64_t>
77 bytesReceived; ///< Map that stores the total bytes received per STA (and addressed to that STA)
78std::map<Mac48Address, uint64_t>
79 packetsTransmitted; ///< Map that stores the total packets transmitted per STA
80std::map<Mac48Address, uint64_t>
81 psduFailed; ///< Map that stores the total number of unsuccessfully received PSDUS (for which
82 ///< the PHY header was successfully received) per STA (including PSDUs not
83 ///< addressed to that STA)
84std::map<Mac48Address, uint64_t>
85 psduSucceeded; ///< Map that stores the total number of successfully received PSDUs per STA
86 ///< (including PSDUs not addressed to that STA)
87std::map<Mac48Address, uint64_t> phyHeaderFailed; ///< Map that stores the total number of
88 ///< unsuccessfully received PHY headers per STA
89std::map<Mac48Address, uint64_t>
90 rxEventWhileTxing; ///< Map that stores the number of reception events per STA that occurred
91 ///< while PHY was already transmitting a PPDU
92std::map<Mac48Address, uint64_t>
93 rxEventWhileRxing; ///< Map that stores the number of reception events per STA that occurred
94 ///< while PHY was already receiving a PPDU
95std::map<Mac48Address, uint64_t>
96 rxEventWhileDecodingPreamble; ///< Map that stores the number of reception events per STA that
97 ///< occurred while PHY was already decoding a preamble
98std::map<Mac48Address, uint64_t>
99 rxEventAbortedByTx; ///< Map that stores the number of reception events aborted per STA because
100 ///< the PHY has started to transmit
101
102std::map<Mac48Address, Time>
103 timeFirstReceived; ///< Map that stores the time at which the first packet was received per STA
104 ///< (and the packet is addressed to that STA)
105std::map<Mac48Address, Time>
106 timeLastReceived; ///< Map that stores the time at which the last packet was received per STA
107 ///< (and the packet is addressed to that STA)
108std::map<Mac48Address, Time> timeFirstTransmitted; ///< Map that stores the time at which the first
109 ///< packet was transmitted per STA
110std::map<Mac48Address, Time> timeLastTransmitted; ///< Map that stores the time at which the last
111 ///< packet was transmitted per STA
112
113std::set<uint32_t> associated; ///< Contains the IDs of the STAs that successfully associated to the
114 ///< access point (in infrastructure mode only)
115
116bool tracing = false; ///< Flag to enable/disable generation of tracing files
117uint32_t pktSize = 1500; ///< packet size used for the simulation (in bytes)
118uint8_t maxMpdus = 0; ///< The maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)
119bool useTxHelper = false; ///< Flag to get MPDU statistics with WifiTxStatsHelper
120bool useRxHelper = false; ///< Flag to get PPDU statistics with WifiPhyRxTraceHelper
121
122/// Table of the expected values for EIFS
123std::map<std::string /* mode */,
124 std::map<unsigned int /* number of nodes */, double /* calculated throughput */>>
126 /* 11b */
127 {"DsssRate1Mbps",
128 {
129 {5, 0.8418},
130 {10, 0.7831},
131 {15, 0.7460},
132 {20, 0.7186},
133 {25, 0.6973},
134 {30, 0.6802},
135 {35, 0.6639},
136 {40, 0.6501},
137 {45, 0.6386},
138 {50, 0.6285},
139 }},
140 {"DsssRate2Mbps",
141 {
142 {5, 1.6170},
143 {10, 1.5075},
144 {15, 1.4371},
145 {20, 1.3849},
146 {25, 1.3442},
147 {30, 1.3115},
148 {35, 1.2803},
149 {40, 1.2538},
150 {45, 1.2317},
151 {50, 1.2124},
152 }},
153 {"DsssRate5_5Mbps",
154 {
155 {5, 3.8565},
156 {10, 3.6170},
157 {15, 3.4554},
158 {20, 3.3339},
159 {25, 3.2385},
160 {30, 3.1613},
161 {35, 3.0878},
162 {40, 3.0249},
163 {45, 2.9725},
164 {50, 2.9266},
165 }},
166 {"DsssRate11Mbps",
167 {
168 {5, 6.3821},
169 {10, 6.0269},
170 {15, 5.7718},
171 {20, 5.5765},
172 {25, 5.4217},
173 {30, 5.2958},
174 {35, 5.1755},
175 {40, 5.0722},
176 {45, 4.9860},
177 {50, 4.9103},
178 }},
179 /* 11a */
180 {"OfdmRate6Mbps",
181 {
182 {5, 4.6899},
183 {10, 4.3197},
184 {15, 4.1107},
185 {20, 3.9589},
186 {25, 3.8478},
187 {30, 3.7490},
188 {35, 3.6618},
189 {40, 3.5927},
190 {45, 3.5358},
191 {50, 3.4711},
192 }},
193 {"OfdmRate9Mbps",
194 {
195 {5, 6.8188},
196 {10, 6.2885},
197 {15, 5.9874},
198 {20, 5.7680},
199 {25, 5.6073},
200 {30, 5.4642},
201 {35, 5.3378},
202 {40, 5.2376},
203 {45, 5.1551},
204 {50, 5.0612},
205 }},
206 {"OfdmRate12Mbps",
207 {
208 {5, 8.8972},
209 {10, 8.2154},
210 {15, 7.8259},
211 {20, 7.5415},
212 {25, 7.3329},
213 {30, 7.1469},
214 {35, 6.9825},
215 {40, 6.8521},
216 {45, 6.7447},
217 {50, 6.6225},
218 }},
219 {"OfdmRate18Mbps",
220 {
221 {5, 12.6719},
222 {10, 11.7273},
223 {15, 11.1814},
224 {20, 10.7810},
225 {25, 10.4866},
226 {30, 10.2237},
227 {35, 9.9910},
228 {40, 9.8061},
229 {45, 9.6538},
230 {50, 9.4804},
231 }},
232 {"OfdmRate24Mbps",
233 {
234 {5, 16.0836},
235 {10, 14.9153},
236 {15, 14.2327},
237 {20, 13.7300},
238 {25, 13.3595},
239 {30, 13.0281},
240 {35, 12.7343},
241 {40, 12.5008},
242 {45, 12.3083},
243 {50, 12.0889},
244 }},
245 {"OfdmRate36Mbps",
246 {
247 {5, 22.0092},
248 {10, 20.4836},
249 {15, 19.5743},
250 {20, 18.8997},
251 {25, 18.4002},
252 {30, 17.9524},
253 {35, 17.5545},
254 {40, 17.2377},
255 {45, 16.9760},
256 {50, 16.6777},
257 }},
258 {"OfdmRate48Mbps",
259 {
260 {5, 26.8382},
261 {10, 25.0509},
262 {15, 23.9672},
263 {20, 23.1581},
264 {25, 22.5568},
265 {30, 22.0165},
266 {35, 21.5355},
267 {40, 21.1519},
268 {45, 20.8348},
269 {50, 20.4729},
270 }},
271 {"OfdmRate54Mbps",
272 {
273 {5, 29.2861},
274 {10, 27.3763},
275 {15, 26.2078},
276 {20, 25.3325},
277 {25, 24.6808},
278 {30, 24.0944},
279 {35, 23.5719},
280 {40, 23.1549},
281 {45, 22.8100},
282 {50, 22.4162},
283 }},
284 /* 11g */
285 {"ErpOfdmRate6Mbps",
286 {
287 {5, 4.6899},
288 {10, 4.3197},
289 {15, 4.1107},
290 {20, 3.9589},
291 {25, 3.8478},
292 {30, 3.7490},
293 {35, 3.6618},
294 {40, 3.5927},
295 {45, 3.5358},
296 {50, 3.4711},
297 }},
298 {"ErpOfdmRate9Mbps",
299 {
300 {5, 6.8188},
301 {10, 6.2885},
302 {15, 5.9874},
303 {20, 5.7680},
304 {25, 5.6073},
305 {30, 5.4642},
306 {35, 5.3378},
307 {40, 5.2376},
308 {45, 5.1551},
309 {50, 5.0612},
310 }},
311 {"ErpOfdmRate12Mbps",
312 {
313 {5, 8.8972},
314 {10, 8.2154},
315 {15, 7.8259},
316 {20, 7.5415},
317 {25, 7.3329},
318 {30, 7.1469},
319 {35, 6.9825},
320 {40, 6.8521},
321 {45, 6.7447},
322 {50, 6.6225},
323 }},
324 {"ErpOfdmRate18Mbps",
325 {
326 {5, 12.6719},
327 {10, 11.7273},
328 {15, 11.1814},
329 {20, 10.7810},
330 {25, 10.4866},
331 {30, 10.2237},
332 {35, 9.9910},
333 {40, 9.8061},
334 {45, 9.6538},
335 {50, 9.4804},
336 }},
337 {"ErpOfdmRate24Mbps",
338 {
339 {5, 16.0836},
340 {10, 14.9153},
341 {15, 14.2327},
342 {20, 13.7300},
343 {25, 13.3595},
344 {30, 13.0281},
345 {35, 12.7343},
346 {40, 12.5008},
347 {45, 12.3083},
348 {50, 12.0889},
349 }},
350 {"ErpOfdmRate36Mbps",
351 {
352 {5, 22.0092},
353 {10, 20.4836},
354 {15, 19.5743},
355 {20, 18.8997},
356 {25, 18.4002},
357 {30, 17.9524},
358 {35, 17.5545},
359 {40, 17.2377},
360 {45, 16.9760},
361 {50, 16.6777},
362 }},
363 {"ErpOfdmRate48Mbps",
364 {
365 {5, 26.8382},
366 {10, 25.0509},
367 {15, 23.9672},
368 {20, 23.1581},
369 {25, 22.5568},
370 {30, 22.0165},
371 {35, 21.5355},
372 {40, 21.1519},
373 {45, 20.8348},
374 {50, 20.4729},
375 }},
376 {"ErpOfdmRate54Mbps",
377 {
378 {5, 29.2861},
379 {10, 27.3763},
380 {15, 26.2078},
381 {20, 25.3325},
382 {25, 24.6808},
383 {30, 24.0944},
384 {35, 23.5719},
385 {40, 23.1549},
386 {45, 22.8100},
387 {50, 22.4162},
388 }},
389 /* 11ax, no frame aggregation */
390 {"HeMcs0_20MHz",
391 {
392 {5, 6.3381},
393 {10, 5.8172},
394 {15, 5.5223},
395 {20, 5.3146},
396 {25, 5.1525},
397 {30, 5.0187},
398 {35, 4.9039},
399 {40, 4.8034},
400 {45, 4.7134},
401 {50, 4.6317},
402 }},
403 {"HeMcs1_20MHz",
404 {
405 {5, 11.6580},
406 {10, 10.7369},
407 {15, 10.2068},
408 {20, 9.8309},
409 {25, 9.5365},
410 {30, 9.2930},
411 {35, 9.0837},
412 {40, 8.9001},
413 {45, 8.7355},
414 {50, 8.5860},
415 }},
416 {"HeMcs2_20MHz",
417 {
418 {5, 15.8572},
419 {10, 14.6445},
420 {15, 13.9367},
421 {20, 13.4323},
422 {25, 13.0361},
423 {30, 12.7076},
424 {35, 12.4249},
425 {40, 12.1766},
426 {45, 11.9538},
427 {50, 11.7511},
428 }},
429 {"HeMcs3_20MHz",
430 {
431 {5, 19.7457},
432 {10, 18.2820},
433 {15, 17.4163},
434 {20, 16.7963},
435 {25, 16.3078},
436 {30, 15.9021},
437 {35, 15.5524},
438 {40, 15.2449},
439 {45, 14.9687},
440 {50, 14.7173},
441 }},
442 {"HeMcs4_20MHz",
443 {
444 {5, 25.8947},
445 {10, 24.0721},
446 {15, 22.9698},
447 {20, 22.1738},
448 {25, 21.5437},
449 {30, 21.0186},
450 {35, 20.5650},
451 {40, 20.1654},
452 {45, 19.8059},
453 {50, 19.4784},
454 }},
455 {"HeMcs5_20MHz",
456 {
457 {5, 30.0542},
458 {10, 28.0155},
459 {15, 26.7625},
460 {20, 25.8523},
461 {25, 25.1295},
462 {30, 24.5258},
463 {35, 24.0034},
464 {40, 23.5426},
465 {45, 23.1277},
466 {50, 22.7492},
467 }},
468 {"HeMcs6_20MHz",
469 {
470 {5, 32.6789},
471 {10, 30.5150},
472 {15, 29.1708},
473 {20, 28.1907},
474 {25, 27.4107},
475 {30, 26.7583},
476 {35, 26.1931},
477 {40, 25.6941},
478 {45, 25.2446},
479 {50, 24.8343},
480 }},
481 {"HeMcs7_20MHz",
482 {
483 {5, 34.1710},
484 {10, 31.9398},
485 {15, 30.5451},
486 {20, 29.5261},
487 {25, 28.7140},
488 {30, 28.0342},
489 {35, 27.4449},
490 {40, 26.9245},
491 {45, 26.4554},
492 {50, 26.0271},
493 }},
494 {"HeMcs8_20MHz",
495 {
496 {5, 37.6051},
497 {10, 35.2296},
498 {15, 33.7228},
499 {20, 32.6160},
500 {25, 31.7314},
501 {30, 30.9895},
502 {35, 30.3455},
503 {40, 29.7760},
504 {45, 29.2623},
505 {50, 28.7929},
506 }},
507 {"HeMcs9_20MHz",
508 {
509 {5, 39.5947},
510 {10, 37.1424},
511 {15, 35.5731},
512 {20, 34.4169},
513 {25, 33.4911},
514 {30, 32.7138},
515 {35, 32.0385},
516 {40, 31.4410},
517 {45, 30.9016},
518 {50, 30.4086},
519 }},
520 {"HeMcs10_20MHz",
521 {
522 {5, 39.5947},
523 {10, 37.1424},
524 {15, 35.5731},
525 {20, 34.4169},
526 {25, 33.4911},
527 {30, 32.7138},
528 {35, 32.0385},
529 {40, 31.4410},
530 {45, 30.9016},
531 {50, 30.4086},
532 }},
533 {"HeMcs11_20MHz",
534 {
535 {5, 41.8065},
536 {10, 39.2749},
537 {15, 37.6383},
538 {20, 36.4282},
539 {25, 35.4575},
540 {30, 34.6414},
541 {35, 33.9316},
542 {40, 33.3031},
543 {45, 32.7355},
544 {50, 32.2164},
545 }},
546 {"HeMcs0_40MHz",
547 {
548 {5, 11.4999},
549 {10, 10.5902},
550 {15, 10.0669},
551 {20, 9.6960},
552 {25, 9.4055},
553 {30, 9.1652},
554 {35, 8.9587},
555 {40, 8.7775},
556 {45, 8.6151},
557 {50, 8.4676},
558 }},
559 {"HeMcs1_40MHz",
560 {
561 {5, 19.5937},
562 {10, 18.1394},
563 {15, 17.2798},
564 {20, 16.6642},
565 {25, 16.1793},
566 {30, 15.7766},
567 {35, 15.4295},
568 {40, 15.1242},
569 {45, 14.8502},
570 {50, 14.6007},
571 }},
572 {"HeMcs2_40MHz",
573 {
574 {5, 25.6338},
575 {10, 23.8255},
576 {15, 22.7329},
577 {20, 21.9442},
578 {25, 21.3200},
579 {30, 20.7999},
580 {35, 20.3506},
581 {40, 19.9549},
582 {45, 19.5990},
583 {50, 19.2746},
584 }},
585 {"HeMcs3_40MHz",
586 {
587 {5, 30.0542},
588 {10, 28.0155},
589 {15, 26.7625},
590 {20, 25.8523},
591 {25, 25.1295},
592 {30, 24.5258},
593 {35, 24.0034},
594 {40, 23.5426},
595 {45, 23.1277},
596 {50, 22.7492},
597 }},
598 {"HeMcs4_40MHz",
599 {
600 {5, 37.6051},
601 {10, 35.2296},
602 {15, 33.7228},
603 {20, 32.6160},
604 {25, 31.7314},
605 {30, 30.9895},
606 {35, 30.3455},
607 {40, 29.7760},
608 {45, 29.2623},
609 {50, 28.7929},
610 }},
611 {"HeMcs5_40MHz",
612 {
613 {5, 41.8065},
614 {10, 39.2749},
615 {15, 37.6383},
616 {20, 36.4282},
617 {25, 35.4575},
618 {30, 34.6414},
619 {35, 33.9316},
620 {40, 33.3031},
621 {45, 32.7355},
622 {50, 32.2164},
623 }},
624 {"HeMcs6_40MHz",
625 {
626 {5, 44.2801},
627 {10, 41.6672},
628 {15, 39.9580},
629 {20, 38.6892},
630 {25, 37.6692},
631 {30, 36.8103},
632 {35, 36.0625},
633 {40, 35.3998},
634 {45, 34.8008},
635 {50, 34.2528},
636 }},
637 {"HeMcs7_40MHz",
638 {
639 {5, 44.2801},
640 {10, 41.6672},
641 {15, 39.9580},
642 {20, 38.6892},
643 {25, 37.6692},
644 {30, 36.8103},
645 {35, 36.0625},
646 {40, 35.3998},
647 {45, 34.8008},
648 {50, 34.2528},
649 }},
650 {"HeMcs8_40MHz",
651 {
652 {5, 47.0648},
653 {10, 44.3699},
654 {15, 42.5825},
655 {20, 41.2495},
656 {25, 40.1751},
657 {30, 39.2689},
658 {35, 38.4790},
659 {40, 37.7781},
660 {45, 37.1443},
661 {50, 36.5639},
662 }},
663 {"HeMcs9_40MHz",
664 {
665 {5, 50.2233},
666 {10, 47.4474},
667 {15, 45.5760},
668 {20, 44.1727},
669 {25, 43.0382},
670 {30, 42.0794},
671 {35, 41.2425},
672 {40, 40.4991},
673 {45, 39.8262},
674 {50, 39.2095},
675 }},
676 {"HeMcs10_40MHz",
677 {
678 {5, 50.2233},
679 {10, 47.4474},
680 {15, 45.5760},
681 {20, 44.1727},
682 {25, 43.0382},
683 {30, 42.0794},
684 {35, 41.2425},
685 {40, 40.4991},
686 {45, 39.8262},
687 {50, 39.2095},
688 }},
689 {"HeMcs11_40MHz",
690 {
691 {5, 50.2233},
692 {10, 47.4474},
693 {15, 45.5760},
694 {20, 44.1727},
695 {25, 43.0382},
696 {30, 42.0794},
697 {35, 41.2425},
698 {40, 40.4991},
699 {45, 39.8262},
700 {50, 39.2095},
701 }},
702 {"HeMcs0_80MHz",
703 {
704 {5, 19.6542},
705 {10, 18.1962},
706 {15, 17.3342},
707 {20, 16.7168},
708 {25, 16.2305},
709 {30, 15.8265},
710 {35, 15.4784},
711 {40, 15.1723},
712 {45, 14.8973},
713 {50, 14.6471},
714 }},
715 {"HeMcs1_80MHz",
716 {
717 {5, 30.9311},
718 {10, 28.8495},
719 {15, 27.5657},
720 {20, 26.6320},
721 {25, 25.8899},
722 {30, 25.2699},
723 {35, 24.7332},
724 {40, 24.2595},
725 {45, 23.8330},
726 {50, 23.4439},
727 }},
728 {"HeMcs2_80MHz",
729 {
730 {5, 37.0575},
731 {10, 34.7039},
732 {15, 33.2146},
733 {20, 32.1216},
734 {25, 31.2485},
735 {30, 30.5164},
736 {35, 29.8811},
737 {40, 29.3194},
738 {45, 28.8127},
739 {50, 28.3499},
740 }},
741 {"HeMcs3_80MHz",
742 {
743 {5, 41.8065},
744 {10, 39.2749},
745 {15, 37.6383},
746 {20, 36.4282},
747 {25, 35.4575},
748 {30, 34.6414},
749 {35, 33.9316},
750 {40, 33.3031},
751 {45, 32.7355},
752 {50, 32.2164},
753 }},
754 {"HeMcs4_80MHz",
755 {
756 {5, 47.0648},
757 {10, 44.3699},
758 {15, 42.5825},
759 {20, 41.2495},
760 {25, 40.1751},
761 {30, 39.2689},
762 {35, 38.4790},
763 {40, 37.7781},
764 {45, 37.1443},
765 {50, 36.5639},
766 }},
767 {"HeMcs5_80MHz",
768 {
769 {5, 50.2233},
770 {10, 47.4474},
771 {15, 45.5760},
772 {20, 44.1727},
773 {25, 43.0382},
774 {30, 42.0794},
775 {35, 41.2425},
776 {40, 40.4991},
777 {45, 39.8262},
778 {50, 39.2095},
779 }},
780 {"HeMcs6_80MHz",
781 {
782 {5, 53.8362},
783 {10, 50.9837},
784 {15, 49.0221},
785 {20, 47.5418},
786 {25, 46.3407},
787 {30, 45.3233},
788 {35, 44.4337},
789 {40, 43.6425},
790 {45, 42.9255},
791 {50, 42.2678},
792 }},
793 {"HeMcs7_80MHz",
794 {
795 {5, 53.8362},
796 {10, 50.9837},
797 {15, 49.0221},
798 {20, 47.5418},
799 {25, 46.3407},
800 {30, 45.3233},
801 {35, 44.4337},
802 {40, 43.6425},
803 {45, 42.9255},
804 {50, 42.2678},
805 }},
806 {"HeMcs8_80MHz",
807 {
808 {5, 53.8362},
809 {10, 50.9837},
810 {15, 49.0221},
811 {20, 47.5418},
812 {25, 46.3407},
813 {30, 45.3233},
814 {35, 44.4337},
815 {40, 43.6425},
816 {45, 42.9255},
817 {50, 42.2678},
818 }},
819 {"HeMcs9_80MHz",
820 {
821 {5, 58.0092},
822 {10, 55.0896},
823 {15, 53.0321},
824 {20, 51.4672},
825 {25, 50.1922},
826 {30, 49.1091},
827 {35, 48.1601},
828 {40, 47.3148},
829 {45, 46.5478},
830 {50, 45.8436},
831 }},
832 {"HeMcs10_80MHz",
833 {
834 {5, 58.0092},
835 {10, 55.0896},
836 {15, 53.0321},
837 {20, 51.4672},
838 {25, 50.1922},
839 {30, 49.1091},
840 {35, 48.1601},
841 {40, 47.3148},
842 {45, 46.5478},
843 {50, 45.8436},
844 }},
845 {"HeMcs11_80MHz",
846 {
847 {5, 58.0092},
848 {10, 55.0896},
849 {15, 53.0321},
850 {20, 51.4672},
851 {25, 50.1922},
852 {30, 49.1091},
853 {35, 48.1601},
854 {40, 47.3148},
855 {45, 46.5478},
856 {50, 45.8436},
857 }},
858 {"HeMcs0_160MHz",
859 {
860 {5, 29.8428},
861 {10, 27.8145},
862 {15, 26.5689},
863 {20, 25.6645},
864 {25, 24.9463},
865 {30, 24.3466},
866 {35, 23.8276},
867 {40, 23.3699},
868 {45, 22.9578},
869 {50, 22.5819},
870 }},
871 {"HeMcs1_160MHz",
872 {
873 {5, 41.1308},
874 {10, 38.6227},
875 {15, 37.0064},
876 {20, 35.8126},
877 {25, 34.8556},
878 {30, 34.0513},
879 {35, 33.3520},
880 {40, 32.7329},
881 {45, 32.1739},
882 {50, 31.6628},
883 }},
884 {"HeMcs2_160MHz",
885 {
886 {5, 46.2101},
887 {10, 43.5393},
888 {15, 41.7755},
889 {20, 40.4620},
890 {25, 39.4041},
891 {30, 38.5123},
892 {35, 37.7353},
893 {40, 37.0461},
894 {45, 36.4229},
895 {50, 35.8524},
896 }},
897 {"HeMcs3_160MHz",
898 {
899 {5, 50.2233},
900 {10, 47.4474},
901 {15, 45.5760},
902 {20, 44.1727},
903 {25, 43.0382},
904 {30, 42.0794},
905 {35, 41.2425},
906 {40, 40.4991},
907 {45, 39.8262},
908 {50, 39.2095},
909 }},
910 {"HeMcs4_160MHz",
911 {
912 {5, 53.8362},
913 {10, 50.9837},
914 {15, 49.0221},
915 {20, 47.5418},
916 {25, 46.3407},
917 {30, 45.3233},
918 {35, 44.4337},
919 {40, 43.6425},
920 {45, 42.9255},
921 {50, 42.2678},
922 }},
923 {"HeMcs5_160MHz",
924 {
925 {5, 58.0092},
926 {10, 55.0896},
927 {15, 53.0321},
928 {20, 51.4672},
929 {25, 50.1922},
930 {30, 49.1091},
931 {35, 48.1601},
932 {40, 47.3148},
933 {45, 46.5478},
934 {50, 45.8436},
935 }},
936 {"HeMcs6_160MHz",
937 {
938 {5, 58.0092},
939 {10, 55.0896},
940 {15, 53.0321},
941 {20, 51.4672},
942 {25, 50.1922},
943 {30, 49.1091},
944 {35, 48.1601},
945 {40, 47.3148},
946 {45, 46.5478},
947 {50, 45.8436},
948 }},
949 {"HeMcs7_160MHz",
950 {
951 {5, 58.0092},
952 {10, 55.0896},
953 {15, 53.0321},
954 {20, 51.4672},
955 {25, 50.1922},
956 {30, 49.1091},
957 {35, 48.1601},
958 {40, 47.3148},
959 {45, 46.5478},
960 {50, 45.8436},
961 }},
962 {"HeMcs8_160MHz",
963 {
964 {5, 58.0092},
965 {10, 55.0896},
966 {15, 53.0321},
967 {20, 51.4672},
968 {25, 50.1922},
969 {30, 49.1091},
970 {35, 48.1601},
971 {40, 47.3148},
972 {45, 46.5478},
973 {50, 45.8436},
974 }},
975 {"HeMcs9_160MHz",
976 {
977 {5, 62.8834},
978 {10, 59.9147},
979 {15, 57.7564},
980 {20, 56.0992},
981 {25, 54.7419},
982 {30, 53.5850},
983 {35, 52.5689},
984 {40, 51.6620},
985 {45, 50.8379},
986 {50, 50.0803},
987 }},
988 {"HeMcs10_160MHz",
989 {
990 {5, 62.8834},
991 {10, 59.9147},
992 {15, 57.7564},
993 {20, 56.0992},
994 {25, 54.7419},
995 {30, 53.5850},
996 {35, 52.5689},
997 {40, 51.6620},
998 {45, 50.8379},
999 {50, 50.0803},
1000 }},
1001 {"HeMcs11_160MHz",
1002 {
1003 {5, 62.8834},
1004 {10, 59.9147},
1005 {15, 57.7564},
1006 {20, 56.0992},
1007 {25, 54.7419},
1008 {30, 53.5850},
1009 {35, 52.5689},
1010 {40, 51.6620},
1011 {45, 50.8379},
1012 {50, 50.0803},
1013 }},
1014};
1015
1016/// Table of the expected values for DIFS
1017std::map<std::string /* mode */,
1018 std::map<unsigned int /* number of nodes */, double /* calculated throughput */>>
1020 /* 11b */
1021 {"DsssRate1Mbps",
1022 {
1023 {5, 0.8437},
1024 {10, 0.7861},
1025 {15, 0.7496},
1026 {20, 0.7226},
1027 {25, 0.7016},
1028 {30, 0.6847},
1029 {35, 0.6686},
1030 {40, 0.6549},
1031 {45, 0.6435},
1032 {50, 0.6336},
1033 }},
1034 {"DsssRate2Mbps",
1035 {
1036 {5, 1.6228},
1037 {10, 1.5168},
1038 {15, 1.4482},
1039 {20, 1.3972},
1040 {25, 1.3574},
1041 {30, 1.3253},
1042 {35, 1.2947},
1043 {40, 1.2687},
1044 {45, 1.2469},
1045 {50, 1.2279},
1046 }},
1047 {"DsssRate5_5Mbps",
1048 {
1049 {5, 3.8896},
1050 {10, 3.6707},
1051 {15, 3.5203},
1052 {20, 3.4063},
1053 {25, 3.3161},
1054 {30, 3.2429},
1055 {35, 3.1729},
1056 {40, 3.1128},
1057 {45, 3.0625},
1058 {50, 3.0184},
1059 }},
1060 {"DsssRate11Mbps",
1061 {
1062 {5, 6.4734},
1063 {10, 6.1774},
1064 {15, 5.9553},
1065 {20, 5.7819},
1066 {25, 5.6429},
1067 {30, 5.5289},
1068 {35, 5.4191},
1069 {40, 5.3243},
1070 {45, 5.2446},
1071 {50, 5.1745},
1072 }},
1073 /* 11a */
1074 {"OfdmRate6Mbps",
1075 {
1076 {5, 4.7087},
1077 {10, 4.3453},
1078 {15, 4.1397},
1079 {20, 3.9899},
1080 {25, 3.8802},
1081 {30, 3.7824},
1082 {35, 3.6961},
1083 {40, 3.6276},
1084 {45, 3.5712},
1085 {50, 3.5071},
1086 }},
1087 {"OfdmRate9Mbps",
1088 {
1089 {5, 6.8586},
1090 {10, 6.3431},
1091 {15, 6.0489},
1092 {20, 5.8340},
1093 {25, 5.6762},
1094 {30, 5.5355},
1095 {35, 5.4110},
1096 {40, 5.3122},
1097 {45, 5.2307},
1098 {50, 5.1380},
1099 }},
1100 {"OfdmRate12Mbps",
1101 {
1102 {5, 8.9515},
1103 {10, 8.2901},
1104 {15, 7.9102},
1105 {20, 7.6319},
1106 {25, 7.4274},
1107 {30, 7.2447},
1108 {35, 7.0829},
1109 {40, 6.9544},
1110 {45, 6.8485},
1111 {50, 6.7278},
1112 }},
1113 {"OfdmRate18Mbps",
1114 {
1115 {5, 12.7822},
1116 {10, 11.8801},
1117 {15, 11.3543},
1118 {20, 10.9668},
1119 {25, 10.6809},
1120 {30, 10.4249},
1121 {35, 10.1978},
1122 {40, 10.0171},
1123 {45, 9.8679},
1124 {50, 9.6978},
1125 }},
1126 {"OfdmRate24Mbps",
1127 {
1128 {5, 16.2470},
1129 {10, 15.1426},
1130 {15, 14.4904},
1131 {20, 14.0072},
1132 {25, 13.6496},
1133 {30, 13.3288},
1134 {35, 13.0436},
1135 {40, 12.8164},
1136 {45, 12.6286},
1137 {50, 12.4144},
1138 }},
1139 {"OfdmRate36Mbps",
1140 {
1141 {5, 22.3164},
1142 {10, 20.9147},
1143 {15, 20.0649},
1144 {20, 19.4289},
1145 {25, 18.9552},
1146 {30, 18.5284},
1147 {35, 18.1476},
1148 {40, 17.8434},
1149 {45, 17.5915},
1150 {50, 17.3036},
1151 }},
1152 {"OfdmRate48Mbps",
1153 {
1154 {5, 27.2963},
1155 {10, 25.6987},
1156 {15, 24.7069},
1157 {20, 23.9578},
1158 {25, 23.3965},
1159 {30, 22.8891},
1160 {35, 22.4350},
1161 {40, 22.0713},
1162 {45, 21.7696},
1163 {50, 21.4243},
1164 }},
1165 {"OfdmRate54Mbps",
1166 {
1167 {5, 29.8324},
1168 {10, 28.1519},
1169 {15, 27.0948},
1170 {20, 26.2925},
1171 {25, 25.6896},
1172 {30, 25.1434},
1173 {35, 24.6539},
1174 {40, 24.2613},
1175 {45, 23.9353},
1176 {50, 23.5618},
1177 }},
1178 /* 11g */
1179 {"ErpOfdmRate6Mbps",
1180 {
1181 {5, 4.7087},
1182 {10, 4.3453},
1183 {15, 4.1397},
1184 {20, 3.9899},
1185 {25, 3.8802},
1186 {30, 3.7824},
1187 {35, 3.6961},
1188 {40, 3.6276},
1189 {45, 3.5712},
1190 {50, 3.5071},
1191 }},
1192 {"ErpOfdmRate9Mbps",
1193 {
1194 {5, 6.8586},
1195 {10, 6.3431},
1196 {15, 6.0489},
1197 {20, 5.8340},
1198 {25, 5.6762},
1199 {30, 5.5355},
1200 {35, 5.4110},
1201 {40, 5.3122},
1202 {45, 5.2307},
1203 {50, 5.1380},
1204 }},
1205 {"ErpOfdmRate12Mbps",
1206 {
1207 {5, 8.9515},
1208 {10, 8.2901},
1209 {15, 7.9102},
1210 {20, 7.6319},
1211 {25, 7.4274},
1212 {30, 7.2447},
1213 {35, 7.0829},
1214 {40, 6.9544},
1215 {45, 6.8485},
1216 {50, 6.7278},
1217 }},
1218 {"ErpOfdmRate18Mbps",
1219 {
1220 {5, 12.7822},
1221 {10, 11.8801},
1222 {15, 11.3543},
1223 {20, 10.9668},
1224 {25, 10.6809},
1225 {30, 10.4249},
1226 {35, 10.1978},
1227 {40, 10.0171},
1228 {45, 9.8679},
1229 {50, 9.6978},
1230 }},
1231 {"ErpOfdmRate24Mbps",
1232 {
1233 {5, 16.2470},
1234 {10, 15.1426},
1235 {15, 14.4904},
1236 {20, 14.0072},
1237 {25, 13.6496},
1238 {30, 13.3288},
1239 {35, 13.0436},
1240 {40, 12.8164},
1241 {45, 12.6286},
1242 {50, 12.4144},
1243 }},
1244 {"ErpOfdmRate36Mbps",
1245 {
1246 {5, 22.3164},
1247 {10, 20.9147},
1248 {15, 20.0649},
1249 {20, 19.4289},
1250 {25, 18.9552},
1251 {30, 18.5284},
1252 {35, 18.1476},
1253 {40, 17.8434},
1254 {45, 17.5915},
1255 {50, 17.3036},
1256 }},
1257 {"ErpOfdmRate48Mbps",
1258 {
1259 {5, 27.2963},
1260 {10, 25.6987},
1261 {15, 24.7069},
1262 {20, 23.9578},
1263 {25, 23.3965},
1264 {30, 22.8891},
1265 {35, 22.4350},
1266 {40, 22.0713},
1267 {45, 21.7696},
1268 {50, 21.4243},
1269 }},
1270 {"ErpOfdmRate54Mbps",
1271 {
1272 {5, 29.8324},
1273 {10, 28.1519},
1274 {15, 27.0948},
1275 {20, 26.2925},
1276 {25, 25.6896},
1277 {30, 25.1434},
1278 {35, 24.6539},
1279 {40, 24.2613},
1280 {45, 23.9353},
1281 {50, 23.5618},
1282 }},
1283 /* 11ax, no frame aggregation */
1284 {"HeMcs0_20MHz",
1285 {
1286 {5, 6.3746},
1287 {10, 5.8670},
1288 {15, 5.5782},
1289 {20, 5.3742},
1290 {25, 5.2147},
1291 {30, 5.0829},
1292 {35, 4.9696},
1293 {40, 4.8703},
1294 {45, 4.7813},
1295 {50, 4.7004},
1296 }},
1297 {"HeMcs1_20MHz",
1298 {
1299 {5, 11.7574},
1300 {10, 10.8735},
1301 {15, 10.3606},
1302 {20, 9.9954},
1303 {25, 9.7084},
1304 {30, 9.4704},
1305 {35, 9.2654},
1306 {40, 9.0853},
1307 {45, 8.9235},
1308 {50, 8.7763},
1309 }},
1310 {"HeMcs2_20MHz",
1311 {
1312 {5, 16.0419},
1313 {10, 14.8998},
1314 {15, 14.2252},
1315 {20, 13.7413},
1316 {25, 13.3594},
1317 {30, 13.0417},
1318 {35, 12.7674},
1319 {40, 12.5258},
1320 {45, 12.3086},
1321 {50, 12.1107},
1322 }},
1323 {"HeMcs3_20MHz",
1324 {
1325 {5, 20.0089},
1326 {10, 18.6480},
1327 {15, 17.8309},
1328 {20, 17.2410},
1329 {25, 16.7736},
1330 {30, 16.3837},
1331 {35, 16.0465},
1332 {40, 15.7491},
1333 {45, 15.4813},
1334 {50, 15.2369},
1335 }},
1336 {"HeMcs4_20MHz",
1337 {
1338 {5, 26.3492},
1339 {10, 24.7107},
1340 {15, 23.6964},
1341 {20, 22.9553},
1342 {25, 22.3640},
1343 {30, 21.8683},
1344 {35, 21.4379},
1345 {40, 21.0571},
1346 {45, 20.7134},
1347 {50, 20.3991},
1348 }},
1349 {"HeMcs5_20MHz",
1350 {
1351 {5, 30.6683},
1352 {10, 28.8843},
1353 {15, 27.7540},
1354 {20, 26.9210},
1355 {25, 26.2528},
1356 {30, 25.6906},
1357 {35, 25.2012},
1358 {40, 24.7671},
1359 {45, 24.3746},
1360 {50, 24.0151},
1361 }},
1362 {"HeMcs6_20MHz",
1363 {
1364 {5, 33.4062},
1365 {10, 31.5485},
1366 {15, 30.3527},
1367 {20, 29.4662},
1368 {25, 28.7527},
1369 {30, 28.1508},
1370 {35, 27.6259},
1371 {40, 27.1597},
1372 {45, 26.7376},
1373 {50, 26.3507},
1374 }},
1375 {"HeMcs7_20MHz",
1376 {
1377 {5, 34.9671},
1378 {10, 33.0739},
1379 {15, 31.8436},
1380 {20, 30.9282},
1381 {25, 30.1900},
1382 {30, 29.5665},
1383 {35, 29.0221},
1384 {40, 28.5382},
1385 {45, 28.0997},
1386 {50, 27.6975},
1387 }},
1388 {"HeMcs8_20MHz",
1389 {
1390 {5, 38.5714},
1391 {10, 36.6144},
1392 {15, 35.3124},
1393 {20, 34.3355},
1394 {25, 33.5438},
1395 {30, 32.8728},
1396 {35, 32.2854},
1397 {40, 31.7623},
1398 {45, 31.2874},
1399 {50, 30.8512},
1400 }},
1401 {"HeMcs9_20MHz",
1402 {
1403 {5, 40.6674},
1404 {10, 38.6851},
1405 {15, 37.3466},
1406 {20, 36.3371},
1407 {25, 35.5165},
1408 {30, 34.8197},
1409 {35, 34.2087},
1410 {40, 33.6638},
1411 {45, 33.1688},
1412 {50, 32.7137},
1413 }},
1414 {"HeMcs10_20MHz",
1415 {
1416 {5, 40.6674},
1417 {10, 38.6851},
1418 {15, 37.3466},
1419 {20, 36.3371},
1420 {25, 35.5165},
1421 {30, 34.8197},
1422 {35, 34.2087},
1423 {40, 33.6638},
1424 {45, 33.1688},
1425 {50, 32.7137},
1426 }},
1427 {"HeMcs11_20MHz",
1428 {
1429 {5, 43.0043},
1430 {10, 41.0039},
1431 {15, 39.6294},
1432 {20, 38.5865},
1433 {25, 37.7358},
1434 {30, 37.0116},
1435 {35, 36.3756},
1436 {40, 35.8076},
1437 {45, 35.2909},
1438 {50, 34.8154},
1439 }},
1440 {"HeMcs0_40MHz",
1441 {
1442 {5, 11.6208},
1443 {10, 10.7566},
1444 {15, 10.2544},
1445 {20, 9.8965},
1446 {25, 9.6151},
1447 {30, 9.3815},
1448 {35, 9.1804},
1449 {40, 9.0035},
1450 {45, 8.8446},
1451 {50, 8.7000},
1452 }},
1453 {"HeMcs1_40MHz",
1454 {
1455 {5, 19.8764},
1456 {10, 18.5328},
1457 {15, 17.7255},
1458 {20, 17.1424},
1459 {25, 16.6803},
1460 {30, 16.2947},
1461 {35, 15.9612},
1462 {40, 15.6668},
1463 {45, 15.4018},
1464 {50, 15.1599},
1465 }},
1466 {"HeMcs2_40MHz",
1467 {
1468 {5, 26.1198},
1469 {10, 24.5088},
1470 {15, 23.5107},
1471 {20, 22.7810},
1472 {25, 22.1986},
1473 {30, 21.7101},
1474 {35, 21.2858},
1475 {40, 20.9104},
1476 {45, 20.5714},
1477 {50, 20.2613},
1478 }},
1479 {"HeMcs3_40MHz",
1480 {
1481 {5, 30.6683},
1482 {10, 28.8843},
1483 {15, 27.7540},
1484 {20, 26.9210},
1485 {25, 26.2528},
1486 {30, 25.6906},
1487 {35, 25.2012},
1488 {40, 24.7671},
1489 {45, 24.3746},
1490 {50, 24.0151},
1491 }},
1492 {"HeMcs4_40MHz",
1493 {
1494 {5, 38.5714},
1495 {10, 36.6144},
1496 {15, 35.3124},
1497 {20, 34.3355},
1498 {25, 33.5438},
1499 {30, 32.8728},
1500 {35, 32.2854},
1501 {40, 31.7623},
1502 {45, 31.2874},
1503 {50, 30.8512},
1504 }},
1505 {"HeMcs5_40MHz",
1506 {
1507 {5, 43.0043},
1508 {10, 41.0039},
1509 {15, 39.6294},
1510 {20, 38.5865},
1511 {25, 37.7358},
1512 {30, 37.0116},
1513 {35, 36.3756},
1514 {40, 35.8076},
1515 {45, 35.2909},
1516 {50, 34.8154},
1517 }},
1518 {"HeMcs6_40MHz",
1519 {
1520 {5, 45.6261},
1521 {10, 43.6185},
1522 {15, 42.2095},
1523 {20, 41.1328},
1524 {25, 40.2509},
1525 {30, 39.4981},
1526 {35, 38.8356},
1527 {40, 38.2430},
1528 {45, 37.7032},
1529 {50, 37.2058},
1530 }},
1531 {"HeMcs7_40MHz",
1532 {
1533 {5, 45.6261},
1534 {10, 43.6185},
1535 {15, 42.2095},
1536 {20, 41.1328},
1537 {25, 40.2509},
1538 {30, 39.4981},
1539 {35, 38.8356},
1540 {40, 38.2430},
1541 {45, 37.7032},
1542 {50, 37.2058},
1543 }},
1544 {"HeMcs8_40MHz",
1545 {
1546 {5, 48.5883},
1547 {10, 46.5892},
1548 {15, 45.1489},
1549 {20, 44.0388},
1550 {25, 43.1252},
1551 {30, 42.3428},
1552 {35, 41.6525},
1553 {40, 41.0338},
1554 {45, 40.4694},
1555 {50, 39.9486},
1556 }},
1557 {"HeMcs9_40MHz",
1558 {
1559 {5, 51.9619},
1560 {10, 49.9941},
1561 {15, 48.5284},
1562 {20, 47.3867},
1563 {25, 46.4416},
1564 {30, 45.6290},
1565 {35, 44.9099},
1566 {40, 44.2640},
1567 {45, 43.6736},
1568 {50, 43.1279},
1569 }},
1570 {"HeMcs10_40MHz",
1571 {
1572 {5, 51.9619},
1573 {10, 49.9941},
1574 {15, 48.5284},
1575 {20, 47.3867},
1576 {25, 46.4416},
1577 {30, 45.6290},
1578 {35, 44.9099},
1579 {40, 44.2640},
1580 {45, 43.6736},
1581 {50, 43.1279},
1582 }},
1583 {"HeMcs11_40MHz",
1584 {
1585 {5, 51.9619},
1586 {10, 49.9941},
1587 {15, 48.5284},
1588 {20, 47.3867},
1589 {25, 46.4416},
1590 {30, 45.6290},
1591 {35, 44.9099},
1592 {40, 44.2640},
1593 {45, 43.6736},
1594 {50, 43.1279},
1595 }},
1596 {"HeMcs0_80MHz",
1597 {
1598 {5, 20.0101},
1599 {10, 18.6928},
1600 {15, 17.8976},
1601 {20, 17.3219},
1602 {25, 16.8648},
1603 {30, 16.4830},
1604 {35, 16.1523},
1605 {40, 15.8603},
1606 {45, 15.5971},
1607 {50, 15.3567},
1608 }},
1609 {"HeMcs1_80MHz",
1610 {
1611 {5, 31.6415},
1612 {10, 29.8575},
1613 {15, 28.7177},
1614 {20, 27.8747},
1615 {25, 27.1971},
1616 {30, 26.6261},
1617 {35, 26.1283},
1618 {40, 25.6865},
1619 {45, 25.2866},
1620 {50, 24.9200},
1621 }},
1622 {"HeMcs2_80MHz",
1623 {
1624 {5, 38.0818},
1625 {10, 36.1730},
1626 {15, 34.9016},
1627 {20, 33.9470},
1628 {25, 33.1729},
1629 {30, 32.5165},
1630 {35, 31.9417},
1631 {40, 31.4295},
1632 {45, 30.9645},
1633 {50, 30.5372},
1634 }},
1635 {"HeMcs3_80MHz",
1636 {
1637 {5, 43.0043},
1638 {10, 41.0039},
1639 {15, 39.6294},
1640 {20, 38.5865},
1641 {25, 37.7358},
1642 {30, 37.0116},
1643 {35, 36.3756},
1644 {40, 35.8076},
1645 {45, 35.2909},
1646 {50, 34.8154},
1647 }},
1648 {"HeMcs4_80MHz",
1649 {
1650 {5, 48.5883},
1651 {10, 46.5892},
1652 {15, 45.1489},
1653 {20, 44.0388},
1654 {25, 43.1252},
1655 {30, 42.3428},
1656 {35, 41.6525},
1657 {40, 41.0338},
1658 {45, 40.4694},
1659 {50, 39.9486},
1660 }},
1661 {"HeMcs5_80MHz",
1662 {
1663 {5, 51.9619},
1664 {10, 49.9941},
1665 {15, 48.5284},
1666 {20, 47.3867},
1667 {25, 46.4416},
1668 {30, 45.6290},
1669 {35, 44.9099},
1670 {40, 44.2640},
1671 {45, 43.6736},
1672 {50, 43.1279},
1673 }},
1674 {"HeMcs6_80MHz",
1675 {
1676 {5, 55.8389},
1677 {10, 53.9360},
1678 {15, 52.4548},
1679 {20, 51.2855},
1680 {25, 50.3106},
1681 {30, 49.4682},
1682 {35, 48.7201},
1683 {40, 48.0462},
1684 {45, 47.4288},
1685 {50, 46.8571},
1686 }},
1687 {"HeMcs7_80MHz",
1688 {
1689 {5, 55.8389},
1690 {10, 53.9360},
1691 {15, 52.4548},
1692 {20, 51.2855},
1693 {25, 50.3106},
1694 {30, 49.4682},
1695 {35, 48.7201},
1696 {40, 48.0462},
1697 {45, 47.4288},
1698 {50, 46.8571},
1699 }},
1700 {"HeMcs8_80MHz",
1701 {
1702 {5, 55.8389},
1703 {10, 53.9360},
1704 {15, 52.4548},
1705 {20, 51.2855},
1706 {25, 50.3106},
1707 {30, 49.4682},
1708 {35, 48.7201},
1709 {40, 48.0462},
1710 {45, 47.4288},
1711 {50, 46.8571},
1712 }},
1713 {"HeMcs9_80MHz",
1714 {
1715 {5, 60.3411},
1716 {10, 58.5527},
1717 {15, 57.0724},
1718 {20, 55.8834},
1719 {25, 54.8827},
1720 {30, 54.0128},
1721 {35, 53.2368},
1722 {40, 52.5352},
1723 {45, 51.8906},
1724 {50, 51.2922},
1725 }},
1726 {"HeMcs10_80MHz",
1727 {
1728 {5, 60.3411},
1729 {10, 58.5527},
1730 {15, 57.0724},
1731 {20, 55.8834},
1732 {25, 54.8827},
1733 {30, 54.0128},
1734 {35, 53.2368},
1735 {40, 52.5352},
1736 {45, 51.8906},
1737 {50, 51.2922},
1738 }},
1739 {"HeMcs11_80MHz",
1740 {
1741 {5, 60.3411},
1742 {10, 58.5527},
1743 {15, 57.0724},
1744 {20, 55.8834},
1745 {25, 54.8827},
1746 {30, 54.0128},
1747 {35, 53.2368},
1748 {40, 52.5352},
1749 {45, 51.8906},
1750 {50, 51.2922},
1751 }},
1752 {"HeMcs0_160MHz",
1753 {
1754 {5, 30.6710},
1755 {10, 28.9919},
1756 {15, 27.9160},
1757 {20, 27.1188},
1758 {25, 26.4770},
1759 {30, 25.9355},
1760 {35, 25.4630},
1761 {40, 25.0432},
1762 {45, 24.6629},
1763 {50, 24.3141},
1764 }},
1765 {"HeMcs1_160MHz",
1766 {
1767 {5, 42.3965},
1768 {10, 40.4510},
1769 {15, 39.1127},
1770 {20, 38.0965},
1771 {25, 37.2670},
1772 {30, 36.5606},
1773 {35, 35.9398},
1774 {40, 35.3852},
1775 {45, 34.8806},
1776 {50, 34.4160},
1777 }},
1778 {"HeMcs2_160MHz",
1779 {
1780 {5, 47.8139},
1781 {10, 45.8767},
1782 {15, 44.4795},
1783 {20, 43.4017},
1784 {25, 42.5141},
1785 {30, 41.7535},
1786 {35, 41.0821},
1787 {40, 40.4801},
1788 {45, 39.9307},
1789 {50, 39.4236},
1790 }},
1791 {"HeMcs3_160MHz",
1792 {
1793 {5, 51.9619},
1794 {10, 49.9941},
1795 {15, 48.5284},
1796 {20, 47.3867},
1797 {25, 46.4416},
1798 {30, 45.6290},
1799 {35, 44.9099},
1800 {40, 44.2640},
1801 {45, 43.6736},
1802 {50, 43.1279},
1803 }},
1804 {"HeMcs4_160MHz",
1805 {
1806 {5, 55.8389},
1807 {10, 53.9360},
1808 {15, 52.4548},
1809 {20, 51.2855},
1810 {25, 50.3106},
1811 {30, 49.4682},
1812 {35, 48.7201},
1813 {40, 48.0462},
1814 {45, 47.4288},
1815 {50, 46.8571},
1816 }},
1817 {"HeMcs5_160MHz",
1818 {
1819 {5, 60.3411},
1820 {10, 58.5527},
1821 {15, 57.0724},
1822 {20, 55.8834},
1823 {25, 54.8827},
1824 {30, 54.0128},
1825 {35, 53.2368},
1826 {40, 52.5352},
1827 {45, 51.8906},
1828 {50, 51.2922},
1829 }},
1830 {"HeMcs6_160MHz",
1831 {
1832 {5, 60.3411},
1833 {10, 58.5527},
1834 {15, 57.0724},
1835 {20, 55.8834},
1836 {25, 54.8827},
1837 {30, 54.0128},
1838 {35, 53.2368},
1839 {40, 52.5352},
1840 {45, 51.8906},
1841 {50, 51.2922},
1842 }},
1843 {"HeMcs7_160MHz",
1844 {
1845 {5, 60.3411},
1846 {10, 58.5527},
1847 {15, 57.0724},
1848 {20, 55.8834},
1849 {25, 54.8827},
1850 {30, 54.0128},
1851 {35, 53.2368},
1852 {40, 52.5352},
1853 {45, 51.8906},
1854 {50, 51.2922},
1855 }},
1856 {"HeMcs8_160MHz",
1857 {
1858 {5, 60.3411},
1859 {10, 58.5527},
1860 {15, 57.0724},
1861 {20, 55.8834},
1862 {25, 54.8827},
1863 {30, 54.0128},
1864 {35, 53.2368},
1865 {40, 52.5352},
1866 {45, 51.8906},
1867 {50, 51.2922},
1868 }},
1869 {"HeMcs9_160MHz",
1870 {
1871 {5, 65.6329},
1872 {10, 64.0336},
1873 {15, 62.5814},
1874 {20, 61.3869},
1875 {25, 60.3690},
1876 {30, 59.4769},
1877 {35, 58.6764},
1878 {40, 57.9495},
1879 {45, 57.2790},
1880 {50, 56.6548},
1881 }},
1882 {"HeMcs10_160MHz",
1883 {
1884 {5, 65.6329},
1885 {10, 64.0336},
1886 {15, 62.5814},
1887 {20, 61.3869},
1888 {25, 60.3690},
1889 {30, 59.4769},
1890 {35, 58.6764},
1891 {40, 57.9495},
1892 {45, 57.2790},
1893 {50, 56.6548},
1894 }},
1895 {"HeMcs11_160MHz",
1896 {
1897 {5, 65.6329},
1898 {10, 64.0336},
1899 {15, 62.5814},
1900 {20, 61.3869},
1901 {25, 60.3690},
1902 {30, 59.4769},
1903 {35, 58.6764},
1904 {40, 57.9495},
1905 {45, 57.2790},
1906 {50, 56.6548},
1907 }},
1908};
1909
1910/**
1911 * Parse context strings of the form "/NodeList/x/DeviceList/x/..." to extract the NodeId integer
1912 *
1913 * @param context The context to parse.
1914 * @return the NodeId
1915 */
1917ContextToNodeId(std::string context)
1918{
1919 std::string sub = context.substr(10);
1920 uint32_t pos = sub.find("/Device");
1921 return std::stoi(sub.substr(0, pos));
1922}
1923
1924/**
1925 * Parse context strings of the form "/NodeList/x/DeviceList/x/..." and fetch the Mac address
1926 *
1927 * @param context The context to parse.
1928 * @return the device MAC address
1929 */
1931ContextToMac(std::string context)
1932{
1933 std::string sub = context.substr(10);
1934 uint32_t pos = sub.find("/Device");
1935 uint32_t nodeId = std::stoi(sub.substr(0, pos));
1936 Ptr<Node> n = NodeList::GetNode(nodeId);
1938 for (uint32_t i = 0; i < n->GetNDevices(); i++)
1939 {
1940 d = n->GetDevice(i)->GetObject<WifiNetDevice>();
1941 if (d)
1942 {
1943 break;
1944 }
1945 }
1946 return Mac48Address::ConvertFrom(d->GetAddress());
1947}
1948
1949// Functions for tracing.
1950
1951/**
1952 * Increment the counter for a given address.
1953 *
1954 * @param [out] counter The counter to increment.
1955 * @param addr The address to increment the counter for.
1956 * @param increment The increment (1 if omitted).
1957 */
1958void
1959IncrementCounter(std::map<Mac48Address, uint64_t>& counter,
1960 Mac48Address addr,
1961 uint64_t increment = 1)
1962{
1963 auto it = counter.find(addr);
1964 if (it != counter.end())
1965 {
1966 it->second += increment;
1967 }
1968 else
1969 {
1970 counter.insert(std::make_pair(addr, increment));
1971 }
1972}
1973
1974/**
1975 * Trace a packet reception.
1976 *
1977 * @param context The context.
1978 * @param p The packet.
1979 * @param channelFreqMhz The channel frequqncy.
1980 * @param txVector The TX vector.
1981 * @param aMpdu The AMPDU.
1982 * @param signalNoise The signal and noise dBm.
1983 * @param staId The STA ID.
1984 */
1985void
1986TracePacketReception(std::string context,
1988 uint16_t channelFreqMhz,
1989 WifiTxVector txVector,
1990 MpduInfo aMpdu,
1991 SignalNoiseDbm signalNoise,
1992 uint16_t staId)
1993{
1994 Ptr<Packet> packet = p->Copy();
1995 if (txVector.IsAggregation())
1996 {
1997 AmpduSubframeHeader subHdr;
1998 uint32_t extractedLength;
1999 packet->RemoveHeader(subHdr);
2000 extractedLength = subHdr.GetLength();
2001 packet = packet->CreateFragment(0, static_cast<uint32_t>(extractedLength));
2002 }
2003 WifiMacHeader hdr;
2004 packet->PeekHeader(hdr);
2005 // hdr.GetAddr1() is the receiving MAC address
2006 if (hdr.GetAddr1() != ContextToMac(context))
2007 {
2008 return;
2009 }
2010 // hdr.GetAddr2() is the sending MAC address
2011 if (packet->GetSize() >= pktSize) // ignore non-data frames
2012 {
2015 auto itTimeFirstReceived = timeFirstReceived.find(hdr.GetAddr2());
2016 if (itTimeFirstReceived == timeFirstReceived.end())
2017 {
2018 timeFirstReceived.insert(std::make_pair(hdr.GetAddr2(), Simulator::Now()));
2019 }
2020 auto itTimeLastReceived = timeLastReceived.find(hdr.GetAddr2());
2021 if (itTimeLastReceived != timeLastReceived.end())
2022 {
2023 itTimeLastReceived->second = Simulator::Now();
2024 }
2025 else
2026 {
2027 timeLastReceived.insert(std::make_pair(hdr.GetAddr2(), Simulator::Now()));
2028 }
2029 }
2030}
2031
2032/**
2033 * Contention window trace.
2034 *
2035 * @param context The context.
2036 * @param cw The contention window.
2037 */
2038void
2039CwTrace(std::string context, uint32_t cw, uint8_t /* linkId */)
2040{
2041 NS_LOG_INFO("CW time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2042 << " val=" << cw);
2043 if (tracing)
2044 {
2045 cwTraceFile << Simulator::Now().GetSeconds() << " " << ContextToNodeId(context) << " " << cw
2046 << std::endl;
2047 }
2048}
2049
2050/**
2051 * Backoff trace.
2052 *
2053 * @param context The context.
2054 * @param newVal The backoff value.
2055 */
2056void
2057BackoffTrace(std::string context, uint32_t newVal, uint8_t /* linkId */)
2058{
2059 NS_LOG_INFO("Backoff time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2060 << " val=" << newVal);
2061 if (tracing)
2062 {
2063 backoffTraceFile << Simulator::Now().GetSeconds() << " " << ContextToNodeId(context) << " "
2064 << newVal << std::endl;
2065 }
2066}
2067
2068/**
2069 * PHY Rx trace.
2070 *
2071 * @param context The context.
2072 * @param p The packet.
2073 * @param power The Rx power.
2074 */
2075void
2077{
2078 NS_LOG_INFO("PHY-RX-START time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2079 << " size=" << p->GetSize());
2080}
2081
2082/**
2083 * PHY Rx trace.
2084 *
2085 * @param context The context.
2086 * @param txVector The TX vector.
2087 * @param psduDuration The PDSU diration.
2088 */
2089void
2090PhyRxPayloadTrace(std::string context, WifiTxVector txVector, Time psduDuration)
2091{
2092 NS_LOG_INFO("PHY-RX-PAYLOAD-START time=" << Simulator::Now()
2093 << " node=" << ContextToNodeId(context)
2094 << " psduDuration=" << psduDuration);
2095}
2096
2097/**
2098 * PHY Drop trace.
2099 *
2100 * @param context The context.
2101 * @param p The packet.
2102 * @param reason The drop reason.
2103 */
2104void
2106{
2107 NS_LOG_INFO("PHY-RX-DROP time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2108 << " size=" << p->GetSize() << " reason=" << reason);
2109 Mac48Address addr = ContextToMac(context);
2110 switch (reason)
2111 {
2113 NS_FATAL_ERROR("RX packet with unsupported settings!");
2114 break;
2115 case CHANNEL_SWITCHING:
2116 NS_FATAL_ERROR("Channel is switching!");
2117 break;
2119 if (p->GetSize() >= pktSize) // ignore non-data frames
2120 {
2122 }
2123 break;
2124 }
2125 case RXING: {
2126 if (p->GetSize() >= pktSize) // ignore non-data frames
2127 {
2129 }
2130 break;
2131 }
2132 case TXING: {
2133 if (p->GetSize() >= pktSize) // ignore non-data frames
2134 {
2136 }
2137 break;
2138 }
2139 case SLEEPING:
2140 NS_FATAL_ERROR("Device is sleeping!");
2141 break;
2143 NS_FATAL_ERROR("Preamble should always be detected!");
2144 break;
2146 if (p->GetSize() >= pktSize) // ignore non-data frames
2147 {
2149 }
2150 break;
2151 }
2152 case L_SIG_FAILURE: {
2153 if (p->GetSize() >= pktSize) // ignore non-data frames
2154 {
2156 }
2157 break;
2158 }
2159 case HT_SIG_FAILURE:
2160 case SIG_A_FAILURE:
2161 case SIG_B_FAILURE:
2162 NS_FATAL_ERROR("Unexpected PHY header failure!");
2164 NS_FATAL_ERROR("All devices should send with same power, so no packet switch during "
2165 "preamble detection should occur!");
2166 break;
2168 NS_FATAL_ERROR("Frame capture should be disabled!");
2169 break;
2170 case OBSS_PD_CCA_RESET:
2171 NS_FATAL_ERROR("Unexpected CCA reset!");
2172 break;
2174 break;
2175 case UNKNOWN:
2176 default:
2177 NS_FATAL_ERROR("Unknown drop reason!");
2178 break;
2179 }
2180}
2181
2182/**
2183 * PHY RX end trace
2184 *
2185 * @param context The context.
2186 * @param p The packet.
2187 */
2188void
2189PhyRxDoneTrace(std::string context, Ptr<const Packet> p)
2190{
2191 NS_LOG_INFO("PHY-RX-END time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2192 << " size=" << p->GetSize());
2193}
2194
2195/**
2196 * PHY successful RX trace
2197 *
2198 * @param context The context.
2199 * @param p The packet.
2200 * @param snr The SNR.
2201 * @param mode The WiFi mode.
2202 * @param preamble The preamble.
2203 */
2204void
2205PhyRxOkTrace(std::string context,
2207 double snr,
2208 WifiMode mode,
2209 WifiPreamble preamble)
2210{
2211 uint8_t nMpdus = (p->GetSize() / pktSize);
2212 NS_LOG_INFO("PHY-RX-OK time=" << Simulator::Now().As(Time::S) << " node="
2213 << ContextToNodeId(context) << " size=" << p->GetSize()
2214 << " nMPDUs=" << +nMpdus << " snr=" << snr << " mode=" << mode
2215 << " preamble=" << preamble);
2216 if ((maxMpdus != 0) && (nMpdus != 0) && (nMpdus != maxMpdus))
2217 {
2218 if (nMpdus > maxMpdus)
2219 {
2220 NS_FATAL_ERROR("A-MPDU settings not properly applied: maximum configured MPDUs is "
2221 << +maxMpdus << " but received an A-MPDU containing " << +nMpdus
2222 << " MPDUs");
2223 }
2224 NS_LOG_WARN("Warning: less MPDUs aggregated in a received A-MPDU ("
2225 << +nMpdus << ") than configured (" << +maxMpdus << ")");
2226 }
2227 if (p->GetSize() >= pktSize) // ignore non-data frames
2228 {
2229 Mac48Address addr = ContextToMac(context);
2231 }
2232}
2233
2234/**
2235 * PHY RX error trace
2236 *
2237 * @param context The context.
2238 * @param p The packet.
2239 * @param snr The SNR.
2240 */
2241void
2242PhyRxErrorTrace(std::string context, Ptr<const Packet> p, double snr)
2243{
2244 NS_LOG_INFO("PHY-RX-ERROR time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2245 << " size=" << p->GetSize() << " snr=" << snr);
2246 if (p->GetSize() >= pktSize) // ignore non-data frames
2247 {
2248 Mac48Address addr = ContextToMac(context);
2250 }
2251}
2252
2253/**
2254 * PHY TX trace
2255 *
2256 * @param context The context.
2257 * @param p The packet.
2258 * @param txPowerW The TX power.
2259 */
2260void
2261PhyTxTrace(std::string context, Ptr<const Packet> p, double txPowerW)
2262{
2263 NS_LOG_INFO("PHY-TX-START time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2264 << " size=" << p->GetSize() << " " << txPowerW);
2265 if (tracing)
2266 {
2268 << " size=" << p->GetSize() << " " << txPowerW << std::endl;
2269 }
2270 if (p->GetSize() >= pktSize) // ignore non-data frames
2271 {
2272 Mac48Address addr = ContextToMac(context);
2274 }
2275}
2276
2277/**
2278 * PHY TX end trace.
2279 *
2280 * @param context The context.
2281 * @param p The packet.
2282 */
2283void
2284PhyTxDoneTrace(std::string context, Ptr<const Packet> p)
2285{
2286 NS_LOG_INFO("PHY-TX-END time=" << Simulator::Now() << " node=" << ContextToNodeId(context)
2287 << " " << p->GetSize());
2288}
2289
2290/**
2291 * MAC TX trace.
2292 *
2293 * @param context The context.
2294 * @param p The packet.
2295 */
2296void
2297MacTxTrace(std::string context, Ptr<const Packet> p)
2298{
2299 if (tracing)
2300 {
2301 macTxTraceFile << Simulator::Now().GetSeconds() << " " << ContextToNodeId(context) << " "
2302 << p->GetSize() << std::endl;
2303 }
2304}
2305
2306/**
2307 * MAC RX trace.
2308 *
2309 * @param context The context.
2310 * @param p The packet.
2311 */
2312void
2313MacRxTrace(std::string context, Ptr<const Packet> p)
2314{
2315 if (tracing)
2316 {
2317 macRxTraceFile << Simulator::Now().GetSeconds() << " " << ContextToNodeId(context) << " "
2318 << p->GetSize() << std::endl;
2319 }
2320}
2321
2322/**
2323 * Socket send trace.
2324 *
2325 * @param context The context.
2326 * @param p The packet.
2327 * @param addr destination address.
2328 */
2329void
2330SocketSendTrace(std::string context, Ptr<const Packet> p, const Address& addr)
2331{
2332 if (tracing)
2333 {
2335 << " " << p->GetSize() << " " << addr << std::endl;
2336 }
2337}
2338
2339/**
2340 * Association log trace.
2341 *
2342 * @param context The context.
2343 * @param address The MAC address.
2344 */
2345void
2346AssociationLog(std::string context, Mac48Address address)
2347{
2348 uint32_t nodeId = ContextToNodeId(context);
2349 auto it = associated.find(nodeId);
2350 if (it == associated.end())
2351 {
2352 NS_LOG_DEBUG("Association: time=" << Simulator::Now() << " node=" << nodeId);
2353 associated.insert(it, nodeId);
2354 }
2355 else
2356 {
2357 NS_FATAL_ERROR(nodeId << " is already associated!");
2358 }
2359}
2360
2361/**
2362 * Deassociation log trace.
2363 *
2364 * @param context The context.
2365 * @param address The MAC address.
2366 */
2367void
2368DisassociationLog(std::string context, Mac48Address address)
2369{
2370 uint32_t nodeId = ContextToNodeId(context);
2371 NS_LOG_DEBUG("Disassociation: time=" << Simulator::Now() << " node=" << nodeId);
2372 NS_FATAL_ERROR("Device should not disassociate!");
2373}
2374
2375/**
2376 * Reset the stats.
2377 */
2378void
2380{
2381 bytesReceived.clear();
2382 packetsReceived.clear();
2383 packetsTransmitted.clear();
2384 psduFailed.clear();
2385 psduSucceeded.clear();
2386 phyHeaderFailed.clear();
2387 timeFirstReceived.clear();
2388 timeLastReceived.clear();
2390 rxEventWhileRxing.clear();
2391 rxEventWhileTxing.clear();
2392 rxEventAbortedByTx.clear();
2393}
2394
2395/**
2396 * Class to configure and run an experiment.
2397 */
2399{
2400 public:
2401 Experiment();
2402
2403 /**
2404 * Configure and run the experiment.
2405 *
2406 * @param wifi the pre-configured WifiHelper
2407 * @param wifiPhy the pre-configured YansWifiPhyHelper
2408 * @param wifiMac the pre-configured WifiMacHelper
2409 * @param wifiChannel the pre-configured YansWifiChannelHelper
2410 * @param trialNumber the trial index
2411 * @param networkSize the number of stations
2412 * @param duration the duration of each simulation run
2413 * @param pcap flag to enable/disable PCAP files generation
2414 * @param infra flag to enable infrastructure model, ring adhoc network if not set
2415 * @param guardIntervalNs the guard interval in ns
2416 * @param distance the distance
2417 * @param apTxPower the AP transmit power
2418 * @param staTxPower the STA transmit power
2419 * @param pktInterval the packet interval
2420 * @return 0 if all went well
2421 *
2422 * Call graph was not generated because of its size.
2423 * @hidecallgraph
2424 */
2425 int Run(const WifiHelper& wifi,
2426 const YansWifiPhyHelper& wifiPhy,
2427 const WifiMacHelper& wifiMac,
2428 const YansWifiChannelHelper& wifiChannel,
2429 uint32_t trialNumber,
2430 uint32_t networkSize,
2431 Time duration,
2432 bool pcap,
2433 bool infra,
2434 uint16_t guardIntervalNs,
2435 meter_u distance,
2436 dBm_u apTxPower,
2437 dBm_u staTxPower,
2438 Time pktInterval);
2439};
2440
2444
2445int
2447 const YansWifiPhyHelper& wifiPhy,
2448 const WifiMacHelper& wifiMac,
2449 const YansWifiChannelHelper& wifiChannel,
2450 uint32_t trialNumber,
2451 uint32_t networkSize,
2452 Time duration,
2453 bool pcap,
2454 bool infra,
2455 uint16_t guardIntervalNs,
2456 meter_u distance,
2457 dBm_u apTxPower,
2458 dBm_u staTxPower,
2459 Time pktInterval)
2460{
2463
2464 NodeContainer wifiNodes;
2465 if (infra)
2466 {
2467 wifiNodes.Create(networkSize + 1);
2468 }
2469 else
2470 {
2471 wifiNodes.Create(networkSize);
2472 }
2473
2474 YansWifiPhyHelper phy = wifiPhy;
2475 phy.SetErrorRateModel("ns3::NistErrorRateModel");
2476 phy.SetChannel(wifiChannel.Create());
2477 phy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
2478
2479 WifiMacHelper mac = wifiMac;
2480 const auto& wifi = helper;
2481 NetDeviceContainer devices;
2482 uint32_t nNodes = wifiNodes.GetN();
2483 if (infra)
2484 {
2485 Ssid ssid = Ssid("wifi-bianchi");
2486 uint64_t beaconInterval = std::min<uint64_t>(
2487 (ceil((duration.GetSeconds() * 1000000) / 1024) * 1024),
2488 (65535 * 1024)); // beacon interval needs to be a multiple of time units (1024 us)
2489 mac.SetType("ns3::ApWifiMac",
2490 "BeaconInterval",
2491 TimeValue(MicroSeconds(beaconInterval)),
2492 "Ssid",
2493 SsidValue(ssid));
2494 phy.Set("TxPowerStart", DoubleValue(apTxPower));
2495 phy.Set("TxPowerEnd", DoubleValue(apTxPower));
2496 devices = wifi.Install(phy, mac, wifiNodes.Get(0));
2497
2498 mac.SetType("ns3::StaWifiMac",
2499 "MaxMissedBeacons",
2500 UintegerValue(std::numeric_limits<uint32_t>::max()),
2501 "Ssid",
2502 SsidValue(ssid));
2503 phy.Set("TxPowerStart", DoubleValue(staTxPower));
2504 phy.Set("TxPowerEnd", DoubleValue(staTxPower));
2505 for (uint32_t i = 1; i < nNodes; ++i)
2506 {
2507 devices.Add(wifi.Install(phy, mac, wifiNodes.Get(i)));
2508 }
2509 }
2510 else
2511 {
2512 mac.SetType("ns3::AdhocWifiMac");
2513 phy.Set("TxPowerStart", DoubleValue(staTxPower));
2514 phy.Set("TxPowerEnd", DoubleValue(staTxPower));
2515 devices = wifi.Install(phy, mac, wifiNodes);
2516 }
2517
2518 WifiHelper::AssignStreams(devices, trialNumber);
2519
2521 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported",
2522 BooleanValue(guardIntervalNs == 400));
2523 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HeConfiguration/GuardInterval",
2524 TimeValue(NanoSeconds(guardIntervalNs)));
2525
2526 // Configure aggregation
2527 for (uint32_t i = 0; i < nNodes; ++i)
2528 {
2529 Ptr<NetDevice> dev = wifiNodes.Get(i)->GetDevice(0);
2531 wifi_dev->GetMac()->SetAttribute("BE_MaxAmpduSize",
2532 UintegerValue(maxMpdus * (pktSize + 50)));
2533 wifi_dev->GetMac()->SetAttribute("BK_MaxAmpduSize",
2534 UintegerValue(maxMpdus * (pktSize + 50)));
2535 wifi_dev->GetMac()->SetAttribute("VO_MaxAmpduSize",
2536 UintegerValue(maxMpdus * (pktSize + 50)));
2537 wifi_dev->GetMac()->SetAttribute("VI_MaxAmpduSize",
2538 UintegerValue(maxMpdus * (pktSize + 50)));
2539 }
2540
2541 MobilityHelper mobility;
2543 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
2544 // Set position for AP
2545 positionAlloc->Add(Vector(1.0, 1.0, 0.0));
2546
2547 // Set position for STAs
2548 const auto angle = (static_cast<degree_u>(360) / (nNodes - 1));
2549 for (uint32_t i = 0; i < (nNodes - 1); ++i)
2550 {
2551 positionAlloc->Add(Vector(1.0 + (distance * cos((i * angle * std::numbers::pi) / 180)),
2552 1.0 + (distance * sin((i * angle * std::numbers::pi) / 180)),
2553 0.0));
2554 }
2555
2556 mobility.SetPositionAllocator(positionAlloc);
2557 mobility.Install(wifiNodes);
2558
2559 PacketSocketHelper packetSocket;
2560 packetSocket.Install(wifiNodes);
2561
2564 startTime->SetAttribute("Stream", IntegerValue(trialNumber));
2565 startTime->SetAttribute("Max", DoubleValue(5.0));
2566
2567 uint32_t i = infra ? 1 : 0;
2568 for (; i < nNodes; ++i)
2569 {
2570 uint32_t j = infra ? 0 : (i + 1) % nNodes;
2571 PacketSocketAddress socketAddr;
2572 socketAddr.SetSingleDevice(devices.Get(i)->GetIfIndex());
2573 socketAddr.SetPhysicalAddress(devices.Get(j)->GetAddress());
2574 socketAddr.SetProtocol(1);
2575
2577 client->SetRemote(socketAddr);
2578 wifiNodes.Get(i)->AddApplication(client);
2579 client->SetAttribute("PacketSize", UintegerValue(pktSize));
2580 client->SetAttribute("MaxPackets", UintegerValue(0));
2581 client->SetAttribute("Interval", TimeValue(pktInterval));
2582 double start = startTime->GetValue();
2583 NS_LOG_DEBUG("Client " << i << " starting at " << start);
2584 client->SetStartTime(Seconds(start));
2585
2587 server->SetLocal(socketAddr);
2588 wifiNodes.Get(j)->AddApplication(server);
2589 }
2590
2591 // Log packet receptions
2593 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx",
2595
2596 // Log association and disassociation
2597 if (infra)
2598 {
2599 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc",
2601 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/DeAssoc",
2603 }
2604
2605 std::string txop =
2606 StaticCast<WifiNetDevice>(wifiNodes.Get(0)->GetDevice(0))->GetMac()->GetQosSupported()
2607 ? "BE_Txop"
2608 : "Txop";
2609 // Trace CW evolution
2610 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/" + txop +
2611 "/CwTrace",
2613 // Trace backoff evolution
2614 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/" + txop +
2615 "/BackoffTrace",
2617 // Trace PHY Tx start events
2618 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxBegin",
2620 // Trace PHY Tx end events
2621 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxEnd",
2623 // Trace PHY Rx start events
2624 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin",
2626 // Trace PHY Rx payload start events
2628 "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxPayloadBegin",
2630 // Trace PHY Rx drop events
2631 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxDrop",
2633 // Trace PHY Rx end events
2634 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxEnd",
2636 // Trace PHY Rx error events
2637 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxError",
2639 // Trace PHY Rx success events
2640 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxOk",
2642 // Trace packet transmission by the device
2643 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
2645 // Trace packet receptions to the device
2646 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
2648 // Trace packets transmitted by the application
2649 Config::Connect("/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::PacketSocketClient/Tx",
2651
2652 WifiTxStatsHelper wifiTxStats;
2653 if (useTxHelper)
2654 {
2655 // Setup Wi-Fi Transmission Statistics Helper (WifiTxStatsHelper) for all devices
2656 wifiTxStats.Enable(devices);
2657 wifiTxStats.Start(Seconds(10));
2658 wifiTxStats.Stop(Seconds(10) + duration);
2659 }
2660
2661 WifiPhyRxTraceHelper rxTraceHelper;
2662 if (useRxHelper)
2663 {
2664 // Setup Wi-Fi PHY Reception Trace Helper (WifiPhyRxTraceHelper) for all devices
2665 rxTraceHelper.Enable(devices);
2666 rxTraceHelper.Start(Seconds(10));
2667 rxTraceHelper.Stop(Seconds(10) + duration);
2668 }
2669
2671 Simulator::Stop(Seconds(10) + duration);
2672
2673 if (pcap)
2674 {
2675 phy.EnablePcap("wifi_bianchi_pcap", devices);
2676 }
2677
2680
2681 if (useTxHelper)
2682 {
2683 // Get results from WifiTxStatsHelper
2684 const auto numSuccessPerNodeDevice = wifiTxStats.GetSuccessesByNodeDevice();
2685 const auto numFailurePerNodeDevice = wifiTxStats.GetFailuresByNodeDevice();
2686 const auto numFailureDueToFailedEnqueuePerNodeDevice =
2688 const auto numFailureDueToExpiredLifetimePerNodeDevice =
2690 const auto numFailureDueToRetryLimitReachedPerNodeDevice =
2692 const auto numFailureDueToQosOldPacketPerNodeDevice =
2694 const auto numRetransPerNodeDevice = wifiTxStats.GetRetransmissionsByNodeDevice();
2695 std::cout << "WifiTxStatsHelper: node to number of MPDUs acked during (10, "
2696 << 10 + duration.ToInteger(Time::S) << "] s:" << std::endl;
2697 if (numSuccessPerNodeDevice.empty())
2698 {
2699 std::cout << "none\n";
2700 }
2701 else
2702 {
2703 std::cout << std::setw(5) << "node" << std::setw(10) << "nSuccess" << std::endl;
2704 for (const auto& [nodeDevTuple, nSuccess] : numSuccessPerNodeDevice)
2705 {
2706 std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10) << nSuccess
2707 << std::endl;
2708 }
2709 }
2710 std::cout
2711 << "WifiTxStatsHelper: node to number of MPDUs failed (due to any reason) during (10, "
2712 << 10 + duration.ToInteger(Time::S) << "] s:" << std::endl;
2713 if (numFailurePerNodeDevice.empty())
2714 {
2715 std::cout << "none\n";
2716 }
2717 else
2718 {
2719 std::cout << std::setw(5) << "node" << std::setw(10) << "nFailed" << std::endl;
2720 for (const auto& [nodeDevTuple, nFailure] : numFailurePerNodeDevice)
2721 {
2722 std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10) << nFailure
2723 << std::endl;
2724 }
2725 std::cout << "WifiTxStatsHelper: node to number of MPDUs failed (due to "
2726 "WIFI_MAC_DROP_FAILED_ENQUEUE) during (10, "
2727 << 10 + duration.ToInteger(Time::S) << "] s:" << std::endl;
2728 if (numFailureDueToFailedEnqueuePerNodeDevice.empty())
2729 {
2730 std::cout << "none\n";
2731 }
2732 else
2733 {
2734 std::cout << std::setw(5) << "node" << std::setw(10) << "nFailed" << std::endl;
2735 for (const auto& [nodeDevTuple, nFailure] :
2736 numFailureDueToFailedEnqueuePerNodeDevice)
2737 {
2738 std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
2739 << nFailure << std::endl;
2740 }
2741 }
2742 std::cout << "WifiTxStatsHelper: node to number of MPDUs failed (due to "
2743 "WIFI_MAC_DROP_EXPIRED_LIFETIME) during (10, "
2744 << 10 + duration.ToInteger(Time::S) << "] s:" << std::endl;
2745 if (numFailureDueToExpiredLifetimePerNodeDevice.empty())
2746 {
2747 std::cout << "none\n";
2748 }
2749 else
2750 {
2751 std::cout << std::setw(5) << "node" << std::setw(10) << "nFailed" << std::endl;
2752 for (const auto& [nodeDevTuple, nFailure] :
2753 numFailureDueToExpiredLifetimePerNodeDevice)
2754 {
2755 std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
2756 << nFailure << std::endl;
2757 }
2758 }
2759 std::cout << "WifiTxStatsHelper: node to number of MPDUs failed (due to "
2760 "WIFI_MAC_DROP_REACHED_RETRY_LIMIT) during (10, "
2761 << 10 + duration.ToInteger(Time::S) << "] s:" << std::endl;
2762 if (numFailureDueToRetryLimitReachedPerNodeDevice.empty())
2763 {
2764 std::cout << "none\n";
2765 }
2766 else
2767 {
2768 std::cout << std::setw(5) << "node" << std::setw(10) << "nFailed" << std::endl;
2769 for (const auto& [nodeDevTuple, nFailure] :
2770 numFailureDueToRetryLimitReachedPerNodeDevice)
2771 {
2772 std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
2773 << nFailure << std::endl;
2774 }
2775 }
2776 std::cout << "WifiTxStatsHelper: node to number of MPDUs failed (due to "
2777 "WIFI_MAC_DROP_QOS_OLD_PACKET) during (10, "
2778 << 10 + duration.ToInteger(Time::S) << "] s:" << std::endl;
2779 if (numFailureDueToQosOldPacketPerNodeDevice.empty())
2780 {
2781 std::cout << "none\n";
2782 }
2783 else
2784 {
2785 std::cout << std::setw(5) << "node" << std::setw(10) << "nFailed" << std::endl;
2786 for (const auto& [nodeDevTuple, nFailure] :
2787 numFailureDueToQosOldPacketPerNodeDevice)
2788 {
2789 std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10)
2790 << nFailure << std::endl;
2791 }
2792 }
2793 }
2794 std::cout << "WifiTxStatsHelper: node to number of retransmissions of MPDUs "
2795 "Acked during (10, "
2796 << 10 + duration.ToInteger(Time::S) << "] s:" << std::endl;
2797 if (numRetransPerNodeDevice.empty())
2798 {
2799 std::cout << "none\n";
2800 }
2801 else
2802 {
2803 std::cout << std::setw(5) << "node" << std::setw(10) << "nRetrans" << std::endl;
2804 for (const auto& [nodeDevTuple, nRetrans] : numRetransPerNodeDevice)
2805 {
2806 std::cout << std::setw(5) << std::get<0>(nodeDevTuple) << std::setw(10) << nRetrans
2807 << std::endl;
2808 }
2809 }
2810 }
2811
2812 if (useRxHelper)
2813 {
2814 // Get results from WifiPhyRxTraceHelper
2815 std::cout << "\nWifiPhyRxTraceHelper: overall statistics" << std::endl;
2816 rxTraceHelper.PrintStatistics();
2817 for (uint32_t nodeIndex = 0; nodeIndex < nNodes; ++nodeIndex)
2818 {
2819 std::cout << "\nWifiPhyRxTraceHelper: per-node statistics for node " << nodeIndex
2820 << std::endl;
2821 rxTraceHelper.PrintStatistics(nodeIndex);
2822 }
2823 std::cout << std::endl;
2824 }
2825
2826 if (tracing)
2827 {
2828 cwTraceFile.flush();
2829 backoffTraceFile.flush();
2830 phyTxTraceFile.flush();
2831 macTxTraceFile.flush();
2832 macRxTraceFile.flush();
2833 socketSendTraceFile.flush();
2834 }
2835
2836 return 0;
2837}
2838
2839/**
2840 * Get the Counter associated with a MAC address.
2841 *
2842 * @param counter The map of counters to inspect.
2843 * @param addr The MAC address.
2844 * @return the value of the counter,
2845 */
2846uint64_t
2847GetCount(const std::map<Mac48Address, uint64_t>& counter, Mac48Address addr)
2848{
2849 uint64_t count = 0;
2850 auto it = counter.find(addr);
2851 if (it != counter.end())
2852 {
2853 count = it->second;
2854 }
2855 return count;
2856}
2857
2858} // unnamed namespace
2859
2860int
2861main(int argc, char* argv[])
2862{
2863 uint32_t nMinStas = 5; ///< Minimum number of STAs to start with
2864 uint32_t nMaxStas = 50; ///< Maximum number of STAs to end with
2865 uint32_t nStepSize = 5; ///< Number of stations to add at each step
2866 uint32_t verbose = 0; ///< verbosity level that increases the number of debugging traces
2867 double duration = 100; ///< duration (in seconds) of each simulation run (i.e. per trial and per
2868 ///< number of stations)
2869 uint32_t trials = 1; ///< Number of runs per point in the plot
2870 bool pcap = false; ///< Flag to enable/disable PCAP files generation
2871 bool infra = false; ///< Flag to enable infrastructure model, ring adhoc network if not set
2872 std::string workDir = "./"; ///< the working directory to store generated files
2873 std::string phyMode =
2874 "OfdmRate54Mbps"; ///< the constant PHY mode string used to transmit frames
2875 std::string standard("11a"); ///< the 802.11 standard
2876 bool validate = false; ///< Flag used for regression in order to verify ns-3 results are in the
2877 ///< expected boundaries
2878 uint16_t plotBianchiModel =
2879 0x01; ///< First bit corresponds to the DIFS model, second bit to the EIFS model
2880 double maxRelativeError =
2881 0.015; ///< Maximum relative error tolerated between ns-3 results and the Bianchi model
2882 ///< (used for regression, i.e. when the validate flag is set)
2883 double frequency = 5; ///< The operating frequency band in GHz: 2.4, 5 or 6
2884 uint16_t channelWidth = 20; ///< The constant channel width in MHz (only for 11n/ac/ax)
2885 uint16_t guardIntervalNs = 800; ///< The guard interval in nanoseconds (800 or 400 for 11n/ac,
2886 ///< 800 or 1600 or 3200 for 11 ax)
2887 uint16_t pktInterval =
2888 1000; ///< The socket packet interval in microseconds (a higher value is needed to reach
2889 ///< saturation conditions as the channel bandwidth or the MCS increases)
2890 meter_u distance = 0.001; ///< The distance in meters between the AP and the STAs
2891 dBm_u apTxPower{16}; ///< The transmit power of the AP (if infrastructure only)
2892 dBm_u staTxPower{16}; ///< The transmit power of each STA (or all STAs if adhoc)
2893
2894 // Disable fragmentation and RTS/CTS
2895 Config::SetDefault("ns3::WifiRemoteStationManager::FragmentationThreshold",
2896 StringValue("22000"));
2897 Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("22000"));
2898 // Make CW stay equal to CWmax until a packet is acknowledged
2899 Config::SetDefault("ns3::WifiMac::FrameRetryLimit", UintegerValue(65535));
2900 // Set maximum queue size to the largest value and set maximum queue delay to be larger than the
2901 // simulation time
2903 "ns3::WifiMacQueue::MaxSize",
2904 QueueSizeValue(QueueSize(QueueSizeUnit::PACKETS, std::numeric_limits<uint32_t>::max())));
2905 Config::SetDefault("ns3::WifiMacQueue::MaxDelay", TimeValue(Seconds(2 * duration)));
2906
2907 CommandLine cmd(__FILE__);
2908 cmd.AddValue("verbose",
2909 "Logging level (0: no log - 1: simulation script logs - 2: all logs)",
2910 verbose);
2911 cmd.AddValue("tracing", "Generate trace files", tracing);
2912 cmd.AddValue("useTxHelper", "Enable WifiTxStatsHelper on all devices", useTxHelper);
2913 cmd.AddValue("useRxHelper", "Enable WifiPhyRxTraceHelper on all devices", useRxHelper);
2914 cmd.AddValue("pktSize", "The packet size in bytes", pktSize);
2915 cmd.AddValue("trials", "The maximal number of runs per network size", trials);
2916 cmd.AddValue("duration", "Time duration for each trial in seconds", duration);
2917 cmd.AddValue("pcap", "Enable/disable PCAP tracing", pcap);
2918 cmd.AddValue("infra", "True to use infrastructure mode, false to use ring adhoc mode", infra);
2919 cmd.AddValue("workDir", "The working directory used to store generated files", workDir);
2920 cmd.AddValue("phyMode", "Set the constant PHY mode string used to transmit frames", phyMode);
2921 cmd.AddValue("standard", "Set the standard (11a, 11b, 11g, 11n, 11ac, 11ax)", standard);
2922 cmd.AddValue("nMinStas", "Minimum number of stations to start with", nMinStas);
2923 cmd.AddValue("nMaxStas", "Maximum number of stations to start with", nMaxStas);
2924 cmd.AddValue("nStepSize", "Number of stations to add at each step", nStepSize);
2925 cmd.AddValue("plotBianchiModel",
2926 "First bit corresponds to the DIFS model, second bit to the EIFS model",
2927 plotBianchiModel);
2928 cmd.AddValue("validate",
2929 "Enable/disable validation of the ns-3 simulations against the Bianchi model",
2930 validate);
2931 cmd.AddValue("maxRelativeError",
2932 "The maximum relative error tolerated between ns-3 results and the Bianchi model "
2933 "(used for regression, i.e. when the validate flag is set)",
2934 maxRelativeError);
2935 cmd.AddValue("frequency", "Set the operating frequency band in GHz: 2.4, 5 or 6", frequency);
2936 cmd.AddValue("channelWidth",
2937 "Set the constant channel width in MHz (only for 11n/ac/ax)",
2938 channelWidth);
2939 cmd.AddValue("guardIntervalNs",
2940 "Set the the guard interval in nanoseconds (800 or 400 for 11n/ac, 800 or 1600 or "
2941 "3200 for 11 ax)",
2942 guardIntervalNs);
2943 cmd.AddValue("maxMpdus",
2944 "Set the maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)",
2945 maxMpdus);
2946 cmd.AddValue("distance", "Set the distance in meters between the AP and the STAs", distance);
2947 cmd.AddValue("apTxPower",
2948 "Set the transmit power of the AP in dBm (if infrastructure only)",
2949 apTxPower);
2950 cmd.AddValue("staTxPower",
2951 "Set the transmit power of each STA in dBm (or all STAs if adhoc)",
2952 staTxPower);
2953 cmd.AddValue("pktInterval", "Set the socket packet interval in microseconds", pktInterval);
2954 cmd.Parse(argc, argv);
2955
2956 if (tracing)
2957 {
2958 cwTraceFile.open("wifi-bianchi-cw-trace.out");
2959 if (!cwTraceFile.is_open())
2960 {
2961 NS_FATAL_ERROR("Failed to open file wifi-bianchi-cw-trace.out");
2962 }
2963 backoffTraceFile.open("wifi-bianchi-backoff-trace.out");
2964 if (!backoffTraceFile.is_open())
2965 {
2966 NS_FATAL_ERROR("Failed to open file wifi-bianchi-backoff-trace.out");
2967 }
2968 phyTxTraceFile.open("wifi-bianchi-phy-tx-trace.out");
2969 if (!phyTxTraceFile.is_open())
2970 {
2971 NS_FATAL_ERROR("Failed to open file wifi-bianchi-phy-tx-trace.out");
2972 }
2973 macTxTraceFile.open("wifi-bianchi-mac-tx-trace.out");
2974 if (!macTxTraceFile.is_open())
2975 {
2976 NS_FATAL_ERROR("Failed to open file wifi-bianchi-mac-tx-trace.out");
2977 }
2978 macRxTraceFile.open("wifi-bianchi-mac-rx-trace.out");
2979 if (!macRxTraceFile.is_open())
2980 {
2981 NS_FATAL_ERROR("Failed to open file wifi-bianchi-mac-rx-trace.out");
2982 }
2983 socketSendTraceFile.open("wifi-bianchi-socket-send-trace.out");
2984 if (!socketSendTraceFile.is_open())
2985 {
2986 NS_FATAL_ERROR("Failed to open file wifi-bianchi-socket-send-trace.out");
2987 }
2988 }
2989
2990 if (verbose >= 1)
2991 {
2992 LogComponentEnable("WifiBianchi", LOG_LEVEL_ALL);
2993 }
2994 else
2995 {
2996 LogComponentEnable("WifiBianchi", LOG_LEVEL_WARN);
2997 }
2998 if (verbose >= 2)
2999 {
3001 }
3002
3003 std::stringstream phyModeStr;
3004 phyModeStr << phyMode;
3005 if (phyMode.find("Mcs") != std::string::npos)
3006 {
3007 phyModeStr << "_" << channelWidth << "MHz";
3008 }
3009
3010 std::stringstream ss;
3011 ss << "wifi-" << standard << "-p-" << pktSize << (infra ? "-infrastructure" : "-adhoc") << "-r-"
3012 << phyModeStr.str() << "-min-" << nMinStas << "-max-" << nMaxStas << "-step-" << nStepSize
3013 << "-throughput.plt";
3014 std::ofstream throughputPlot(ss.str());
3015 ss.str("");
3016 ss << "wifi-" << standard << "-p-" << pktSize << (infra ? "-infrastructure" : "-adhoc") << "-r-"
3017 << phyModeStr.str() << "-min-" << nMinStas << "-max-" << nMaxStas << "-step-" << nStepSize
3018 << "-throughput.eps";
3019 Gnuplot gnuplot = Gnuplot(ss.str());
3020
3021 WifiStandard wifiStandard;
3022 if (standard == "11a")
3023 {
3024 wifiStandard = WIFI_STANDARD_80211a;
3025 frequency = 5;
3026 channelWidth = 20;
3027 }
3028 else if (standard == "11b")
3029 {
3030 wifiStandard = WIFI_STANDARD_80211b;
3031 frequency = 2.4;
3032 channelWidth = 22;
3033 }
3034 else if (standard == "11g")
3035 {
3036 wifiStandard = WIFI_STANDARD_80211g;
3037 frequency = 2.4;
3038 channelWidth = 20;
3039 }
3040 else if (standard == "11n")
3041 {
3042 if (frequency == 2.4 || frequency == 5)
3043 {
3044 wifiStandard = WIFI_STANDARD_80211n;
3045 }
3046 else
3047 {
3048 NS_FATAL_ERROR("Unsupported frequency band " << frequency << " GHz for standard "
3049 << standard);
3050 }
3051 }
3052 else if (standard == "11ac")
3053 {
3054 wifiStandard = WIFI_STANDARD_80211ac;
3055 frequency = 5;
3056 }
3057 else if (standard == "11ax")
3058 {
3059 if (frequency == 2.4 || frequency == 5 || frequency == 6)
3060 {
3061 wifiStandard = WIFI_STANDARD_80211ax;
3062 }
3063 else
3064 {
3065 NS_FATAL_ERROR("Unsupported frequency band " << frequency << " GHz for standard "
3066 << standard);
3067 }
3068 }
3069 else
3070 {
3071 NS_FATAL_ERROR("Unsupported standard: " << standard);
3072 }
3073
3074 std::string channelStr = "{0, " + std::to_string(channelWidth) + ", BAND_" +
3075 (frequency == 2.4 ? "2_4" : (frequency == 5 ? "5" : "6")) + "GHZ, 0}";
3076 Config::SetDefault("ns3::WifiPhy::ChannelSettings", StringValue(channelStr));
3077
3078 YansWifiPhyHelper wifiPhy;
3080
3081 YansWifiChannelHelper wifiChannel;
3082 wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
3083 if (frequency == 6)
3084 {
3085 // Reference Loss for Friss at 1 m with 6.0 GHz
3086 wifiChannel.AddPropagationLoss("ns3::LogDistancePropagationLossModel",
3087 "Exponent",
3088 DoubleValue(2.0),
3089 "ReferenceDistance",
3090 DoubleValue(1.0),
3091 "ReferenceLoss",
3092 DoubleValue(49.013));
3093 }
3094 else if (frequency == 5)
3095 {
3096 // Reference Loss for Friss at 1 m with 5.15 GHz
3097 wifiChannel.AddPropagationLoss("ns3::LogDistancePropagationLossModel",
3098 "Exponent",
3099 DoubleValue(2.0),
3100 "ReferenceDistance",
3101 DoubleValue(1.0),
3102 "ReferenceLoss",
3103 DoubleValue(46.6777));
3104 }
3105 else
3106 {
3107 // Reference Loss for Friss at 1 m with 2.4 GHz
3108 wifiChannel.AddPropagationLoss("ns3::LogDistancePropagationLossModel",
3109 "Exponent",
3110 DoubleValue(2.0),
3111 "ReferenceDistance",
3112 DoubleValue(1.0),
3113 "ReferenceLoss",
3114 DoubleValue(40.046));
3115 }
3116
3118 wifi.SetStandard(wifiStandard);
3119 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
3120 "DataMode",
3121 StringValue(phyMode),
3122 "ControlMode",
3123 StringValue(phyMode));
3124
3125 Gnuplot2dDataset dataset;
3126 Gnuplot2dDataset datasetBianchiEifs;
3127 Gnuplot2dDataset datasetBianchiDifs;
3130 datasetBianchiEifs.SetStyle(Gnuplot2dDataset::LINES_POINTS);
3131 datasetBianchiDifs.SetStyle(Gnuplot2dDataset::LINES_POINTS);
3132
3134 WifiMacHelper wifiMac;
3135 double averageThroughput;
3136 std::vector<double> throughputArray(trials);
3137 for (uint32_t n = nMinStas; n <= nMaxStas; n += nStepSize)
3138 {
3139 averageThroughput = 0;
3140 double throughput;
3141 for (uint32_t runIndex = 0; runIndex < trials; runIndex++)
3142 {
3143 packetsReceived.clear();
3144 bytesReceived.clear();
3145 packetsTransmitted.clear();
3146 psduFailed.clear();
3147 psduSucceeded.clear();
3148 phyHeaderFailed.clear();
3149 timeFirstReceived.clear();
3150 timeLastReceived.clear();
3152 rxEventWhileRxing.clear();
3153 rxEventWhileTxing.clear();
3154 rxEventAbortedByTx.clear();
3155 associated.clear();
3156 throughput = 0;
3157 std::cout << "Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str()
3158 << " for " << n << " nodes " << std::endl;
3159 if (tracing)
3160 {
3161 cwTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "
3162 << phyModeStr.str() << " for " << n << " nodes" << std::endl;
3163 backoffTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "
3164 << phyModeStr.str() << " for " << n << " nodes" << std::endl;
3165 phyTxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "
3166 << phyModeStr.str() << " for " << n << " nodes" << std::endl;
3167 macTxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "
3168 << phyModeStr.str() << " for " << n << " nodes" << std::endl;
3169 macRxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "
3170 << phyModeStr.str() << " for " << n << " nodes" << std::endl;
3171 socketSendTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "
3172 << phyModeStr.str() << " for " << n << " nodes" << std::endl;
3173 }
3174 experiment.Run(wifi,
3175 wifiPhy,
3176 wifiMac,
3177 wifiChannel,
3178 runIndex,
3179 n,
3180 Seconds(duration),
3181 pcap,
3182 infra,
3183 guardIntervalNs,
3184 distance,
3185 apTxPower,
3186 staTxPower,
3187 MicroSeconds(pktInterval));
3188 uint32_t k = 0;
3189 if (bytesReceived.size() != n)
3190 {
3191 NS_FATAL_ERROR("Not all stations got traffic!");
3192 }
3193 for (auto it = bytesReceived.begin(); it != bytesReceived.end(); it++, k++)
3194 {
3195 Time first = timeFirstReceived.find(it->first)->second;
3196 Time last = timeLastReceived.find(it->first)->second;
3197 Time dataTransferDuration = last - first;
3198 double nodeThroughput =
3199 (it->second * 8 / static_cast<double>(dataTransferDuration.GetMicroSeconds()));
3200 throughput += nodeThroughput;
3201 uint64_t nodeTxPackets = GetCount(packetsTransmitted, it->first);
3202 uint64_t nodeRxPackets = GetCount(packetsReceived, it->first);
3203 uint64_t nodePhyHeaderFailures = GetCount(phyHeaderFailed, it->first);
3204 uint64_t nodePsduFailures = GetCount(psduFailed, it->first);
3205 uint64_t nodePsduSuccess = GetCount(psduSucceeded, it->first);
3206 uint64_t nodeRxEventWhileDecodingPreamble =
3208 uint64_t nodeRxEventWhileRxing = GetCount(rxEventWhileRxing, it->first);
3209 uint64_t nodeRxEventWhileTxing = GetCount(rxEventWhileTxing, it->first);
3210 uint64_t nodeRxEventAbortedByTx = GetCount(rxEventAbortedByTx, it->first);
3211 uint64_t nodeRxEvents = nodePhyHeaderFailures + nodePsduFailures + nodePsduSuccess +
3212 nodeRxEventWhileDecodingPreamble + nodeRxEventWhileRxing +
3213 nodeRxEventWhileTxing + nodeRxEventAbortedByTx;
3214 std::cout << "Node " << it->first << ": TX packets " << nodeTxPackets
3215 << "; RX packets " << nodeRxPackets << "; PHY header failures "
3216 << nodePhyHeaderFailures << "; PSDU failures " << nodePsduFailures
3217 << "; PSDU success " << nodePsduSuccess
3218 << "; RX events while decoding preamble "
3219 << nodeRxEventWhileDecodingPreamble << "; RX events while RXing "
3220 << nodeRxEventWhileRxing << "; RX events while TXing "
3221 << nodeRxEventWhileTxing << "; RX events aborted by TX "
3222 << nodeRxEventAbortedByTx << "; total RX events " << nodeRxEvents
3223 << "; total events " << nodeTxPackets + nodeRxEvents << "; time first RX "
3224 << first << "; time last RX " << last << "; dataTransferDuration "
3225 << dataTransferDuration << "; throughput " << nodeThroughput << " Mbps"
3226 << std::endl;
3227 }
3228 std::cout << "Total throughput: " << throughput << " Mbps" << std::endl;
3229 averageThroughput += throughput;
3230 throughputArray[runIndex] = throughput;
3231 }
3232 averageThroughput = averageThroughput / trials;
3233
3234 bool rateFound = false;
3235 double relativeErrorDifs = 0;
3236 double relativeErrorEifs = 0;
3237 auto itDifs = bianchiResultsDifs.find(phyModeStr.str());
3238 if (itDifs != bianchiResultsDifs.end())
3239 {
3240 rateFound = true;
3241 auto it = itDifs->second.find(n);
3242 if (it != itDifs->second.end())
3243 {
3244 relativeErrorDifs = (std::abs(averageThroughput - it->second) / it->second);
3245 std::cout << "Relative error (DIFS): " << 100 * relativeErrorDifs << "%"
3246 << std::endl;
3247 }
3248 else if (validate)
3249 {
3250 NS_FATAL_ERROR("No Bianchi results (DIFS) calculated for that number of stations!");
3251 }
3252 }
3253 auto itEifs = bianchiResultsEifs.find(phyModeStr.str());
3254 if (itEifs != bianchiResultsEifs.end())
3255 {
3256 rateFound = true;
3257 auto it = itEifs->second.find(n);
3258 if (it != itEifs->second.end())
3259 {
3260 relativeErrorEifs = (std::abs(averageThroughput - it->second) / it->second);
3261 std::cout << "Relative error (EIFS): " << 100 * relativeErrorEifs << "%"
3262 << std::endl;
3263 }
3264 else if (validate)
3265 {
3266 NS_FATAL_ERROR("No Bianchi results (EIFS) calculated for that number of stations!");
3267 }
3268 }
3269 if (!rateFound && validate)
3270 {
3271 NS_FATAL_ERROR("No Bianchi results calculated for that rate!");
3272 }
3273 double relativeError = std::min(relativeErrorDifs, relativeErrorEifs);
3274 if (validate && (relativeError > maxRelativeError))
3275 {
3276 NS_FATAL_ERROR("Relative error is too high!");
3277 }
3278
3279 double stDev = 0;
3280 for (uint32_t i = 0; i < trials; ++i)
3281 {
3282 stDev += pow(throughputArray[i] - averageThroughput, 2);
3283 }
3284 stDev = sqrt(stDev / (trials - 1));
3285 dataset.Add(n, averageThroughput, stDev);
3286 }
3287 dataset.SetTitle("ns-3");
3288
3289 auto itDifs = bianchiResultsDifs.find(phyModeStr.str());
3290 if (itDifs != bianchiResultsDifs.end())
3291 {
3292 for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
3293 {
3294 double value = 0.0;
3295 auto it = itDifs->second.find(i);
3296 if (it != itDifs->second.end())
3297 {
3298 value = it->second;
3299 }
3300 datasetBianchiDifs.Add(i, value);
3301 }
3302 }
3303 else
3304 {
3305 for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
3306 {
3307 datasetBianchiDifs.Add(i, 0.0);
3308 }
3309 }
3310
3311 auto itEifs = bianchiResultsEifs.find(phyModeStr.str());
3312 if (itEifs != bianchiResultsEifs.end())
3313 {
3314 for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
3315 {
3316 double value = 0.0;
3317 auto it = itEifs->second.find(i);
3318 if (it != itEifs->second.end())
3319 {
3320 value = it->second;
3321 }
3322 datasetBianchiEifs.Add(i, value);
3323 }
3324 }
3325 else
3326 {
3327 for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
3328 {
3329 datasetBianchiEifs.Add(i, 0.0);
3330 }
3331 }
3332
3333 datasetBianchiEifs.SetTitle("Bianchi (EIFS - lower bound)");
3334 datasetBianchiDifs.SetTitle("Bianchi (DIFS - upper bound)");
3335 gnuplot.AddDataset(dataset);
3336 gnuplot.SetTerminal("postscript eps color enh \"Times-BoldItalic\"");
3337 gnuplot.SetLegend("Number of competing stations", "Throughput (Mbps)");
3338 ss.str("");
3339 ss << "Frame size " << pktSize << " bytes";
3340 gnuplot.SetTitle(ss.str());
3341 ss.str("");
3342 ss << "set xrange [" << nMinStas << ":" << nMaxStas << "]\n"
3343 << "set xtics " << nStepSize << "\n"
3344 << "set grid xtics ytics\n"
3345 << "set mytics\n"
3346 << "set style line 1 linewidth 5\n"
3347 << "set style line 2 linewidth 5\n"
3348 << "set style line 3 linewidth 5\n"
3349 << "set style line 4 linewidth 5\n"
3350 << "set style line 5 linewidth 5\n"
3351 << "set style line 6 linewidth 5\n"
3352 << "set style line 7 linewidth 5\n"
3353 << "set style line 8 linewidth 5\n"
3354 << "set style increment user";
3355 gnuplot.SetExtra(ss.str());
3356 if (plotBianchiModel & 0x0001)
3357 {
3358 datasetBianchiDifs.SetTitle("Bianchi");
3359 gnuplot.AddDataset(datasetBianchiDifs);
3360 }
3361 if (plotBianchiModel & 0x0002)
3362 {
3363 datasetBianchiEifs.SetTitle("Bianchi");
3364 gnuplot.AddDataset(datasetBianchiEifs);
3365 }
3366 if (plotBianchiModel == 0x0003)
3367 {
3368 datasetBianchiEifs.SetTitle("Bianchi (EIFS - lower bound)");
3369 datasetBianchiDifs.SetTitle("Bianchi (DIFS - upper bound)");
3370 }
3371 gnuplot.GenerateOutput(throughputPlot);
3372 throughputPlot.close();
3373
3374 if (tracing)
3375 {
3376 cwTraceFile.close();
3377 backoffTraceFile.close();
3378 phyTxTraceFile.close();
3379 macTxTraceFile.close();
3380 macRxTraceFile.close();
3381 socketSendTraceFile.close();
3382 }
3383
3384 return 0;
3385}
Gnuplot2dDataset Run(const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel)
Run an experiment.
int Run(const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel, uint32_t trialNumber, uint32_t networkSize, Time duration, bool pcap, bool infra, uint16_t guardIntervalNs, meter_u distance, dBm_u apTxPower, dBm_u staTxPower, Time pktInterval)
Configure and run the experiment.
a polymophic address class
Definition address.h:114
Headers for A-MPDU subframes.
uint16_t GetLength() const
Return the length field.
holds a vector of ns3::Application pointers.
AttributeValue implementation for Boolean.
Definition boolean.h:26
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Class to represent a 2D points plot.
Definition gnuplot.h:105
void SetErrorBars(ErrorBars errorBars)
Definition gnuplot.cc:360
void SetStyle(Style style)
Definition gnuplot.cc:348
void Add(double x, double y)
Definition gnuplot.cc:366
void SetTitle(const std::string &title)
Change line title.
Definition gnuplot.cc:137
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition gnuplot.h:359
void AddDataset(const GnuplotDataset &dataset)
Definition gnuplot.cc:785
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition gnuplot.cc:765
void SetTerminal(const std::string &terminal)
Definition gnuplot.cc:753
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition gnuplot.cc:791
void SetExtra(const std::string &extra)
Definition gnuplot.cc:772
void SetTitle(const std::string &title)
Definition gnuplot.cc:759
Hold a signed integer type.
Definition integer.h:34
an EUI-48 address
static Mac48Address ConvertFrom(const Address &address)
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition node.cc:153
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition node.cc:138
static Ptr< Node > GetNode(uint32_t n)
Definition node-list.cc:240
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
Class for representing queue sizes.
Definition queue-size.h:85
AttributeValue implementation for QueueSize.
Definition queue-size.h:210
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:125
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
static void Run()
Run the simulation.
Definition simulator.cc:161
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:169
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:96
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:399
@ S
second
Definition nstime.h:107
int64_t ToInteger(Unit unit) const
Get the Time value expressed in a particular unit.
Definition nstime.h:569
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:409
AttributeValue implementation for Time.
Definition nstime.h:1483
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
static void EnableLogComponents(LogLevel logLevel=LOG_LEVEL_ALL)
Helper to enable all WifiNetDevice log components with one statement.
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
create MAC layers for a ns3::WifiNetDevice.
represent a single transmission mode
Definition wifi-mode.h:38
Hold together all Wifi-related objects.
void DisablePreambleDetectionModel()
Disable the preamble detection model on all links.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
Assists in tracing and analyzing Wi-Fi Physical Layer (PHY) receptions.
void PrintStatistics() const
Print statistics for all nodes, devices, and links during the collection period.
void Stop(Time stopTime)
Stops the collection of statistics at a specified time.
void Enable(NodeContainer nodes)
Enables trace collection for all nodes and WifiNetDevices in the specified NodeContainer.
void Start(Time startTime)
Starts the collection of statistics from a specified start time.
Statistics helper for tracking outcomes of data MPDU transmissions.
void Stop(Time stopTime)
Set the stop time for statistics collection.
CountPerNodeDevice_t GetFailuresByNodeDevice() const
Return the counts of failed MPDU transmissions in a hash map.
CountPerNodeDevice_t GetSuccessesByNodeDevice() const
Return the counts of successful MPDU transmissions in a hash map.
void Enable(const NodeContainer &nodes)
Enables trace collection for all nodes and WifiNetDevices in the specified NodeContainer.
CountPerNodeDevice_t GetRetransmissionsByNodeDevice() const
Return the counts of MPDU retransmissions in a hash map.
void Start(Time startTime)
Set the start time for statistics collection.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
manage and create wifi channel objects for the YANS model.
void SetPropagationDelay(std::string name, Ts &&... args)
void AddPropagationLoss(std::string name, Ts &&... args)
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void experiment(std::string queue_disc_type)
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:690
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:886
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
void Set(std::string path, const AttributeValue &value)
Definition config.cc:872
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:253
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
@ PACKETS
Use number of packets for queue size.
Definition queue-size.h:34
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1415
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1432
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1381
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ OBSS_PD_CCA_RESET
@ PREAMBLE_DETECT_FAILURE
@ FRAME_CAPTURE_PACKET_SWITCH
@ UNSUPPORTED_SETTINGS
@ L_SIG_FAILURE
@ SIGNAL_DETECTION_ABORTED_BY_TX
@ RECEPTION_ABORTED_BY_TX
@ SIG_A_FAILURE
@ CHANNEL_SWITCHING
@ BUSY_DECODING_PREAMBLE
@ SIG_B_FAILURE
@ HT_SIG_FAILURE
@ PREAMBLE_DETECTION_PACKET_SWITCH
@ WIFI_MAC_DROP_QOS_OLD_PACKET
Definition wifi-mac.h:75
@ WIFI_MAC_DROP_FAILED_ENQUEUE
Definition wifi-mac.h:72
@ WIFI_MAC_DROP_EXPIRED_LIFETIME
Definition wifi-mac.h:73
@ WIFI_MAC_DROP_REACHED_RETRY_LIMIT
Definition wifi-mac.h:74
std::ofstream socketSendTraceFile
File that traces packets transmitted by the application over time.
bool tracing
Flag to enable/disable generation of tracing files.
uint8_t maxMpdus
The maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation).
Mac48Address ContextToMac(std::string context)
Parse context strings of the form "/NodeList/x/DeviceList/x/..." and fetch the Mac address.
std::map< Mac48Address, uint64_t > rxEventWhileDecodingPreamble
Map that stores the number of reception events per STA that occurred while PHY was already decoding a...
std::ofstream macTxTraceFile
File that traces MAC transmissions over time.
std::map< Mac48Address, uint64_t > rxEventWhileTxing
Map that stores the number of reception events per STA that occurred while PHY was already transmitti...
std::ofstream cwTraceFile
File that traces CW over time.
std::set< uint32_t > associated
Contains the IDs of the STAs that successfully associated to the access point (in infrastructure mode...
std::map< Mac48Address, uint64_t > packetsTransmitted
Map that stores the total packets transmitted per STA.
void PhyTxDoneTrace(std::string context, Ptr< const Packet > p)
PHY TX end trace.
uint32_t pktSize
packet size used for the simulation (in bytes)
bool useRxHelper
Flag to get PPDU statistics with WifiPhyRxTraceHelper.
std::map< Mac48Address, uint64_t > bytesReceived
Map that stores the total bytes received per STA (and addressed to that STA).
std::map< Mac48Address, uint64_t > packetsReceived
Map that stores the total packets received per STA (and addressed to that STA).
void TracePacketReception(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
Trace a packet reception.
uint32_t ContextToNodeId(std::string context)
Parse context strings of the form "/NodeList/x/DeviceList/x/..." to extract the NodeId integer.
void AssociationLog(std::string context, Mac48Address address)
Association log trace.
void PhyRxTrace(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand power)
PHY Rx trace.
void PhyRxErrorTrace(std::string context, Ptr< const Packet > p, double snr)
PHY RX error trace.
void PhyRxOkTrace(std::string context, Ptr< const Packet > p, double snr, WifiMode mode, WifiPreamble preamble)
PHY successful RX trace.
std::map< Mac48Address, uint64_t > phyHeaderFailed
Map that stores the total number of unsuccessfully received PHY headers per STA.
std::map< Mac48Address, Time > timeFirstReceived
Map that stores the time at which the first packet was received per STA (and the packet is addressed ...
std::ofstream backoffTraceFile
File that traces backoff over time.
void DisassociationLog(std::string context, Mac48Address address)
Deassociation log trace.
std::map< Mac48Address, uint64_t > rxEventWhileRxing
Map that stores the number of reception events per STA that occurred while PHY was already receiving ...
void PhyRxDoneTrace(std::string context, Ptr< const Packet > p)
PHY RX end trace.
void PhyTxTrace(std::string context, Ptr< const Packet > p, double txPowerW)
PHY TX trace.
std::map< Mac48Address, uint64_t > psduFailed
Map that stores the total number of unsuccessfully received PSDUS (for which the PHY header was succe...
std::map< Mac48Address, uint64_t > rxEventAbortedByTx
Map that stores the number of reception events aborted per STA because the PHY has started to transmi...
void CwTrace(std::string context, uint32_t cw, uint8_t)
Contention window trace.
std::map< std::string, std::map< unsigned int, double > > bianchiResultsEifs
Table of the expected values for EIFS.
uint64_t GetCount(const std::map< Mac48Address, uint64_t > &counter, Mac48Address addr)
Get the Counter associated with a MAC address.
void IncrementCounter(std::map< Mac48Address, uint64_t > &counter, Mac48Address addr, uint64_t increment=1)
Increment the counter for a given address.
bool useTxHelper
Flag to get MPDU statistics with WifiTxStatsHelper.
std::ofstream phyTxTraceFile
File that traces PHY transmissions over time.
std::map< Mac48Address, Time > timeLastReceived
Map that stores the time at which the last packet was received per STA (and the packet is addressed t...
std::map< std::string, std::map< unsigned int, double > > bianchiResultsDifs
Table of the expected values for DIFS.
void MacTxTrace(std::string context, Ptr< const Packet > p)
MAC TX trace.
void SocketSendTrace(std::string context, Ptr< const Packet > p, const Address &addr)
Socket send trace.
std::ofstream macRxTraceFile
File that traces MAC receptions over time.
std::map< Mac48Address, uint64_t > psduSucceeded
Map that stores the total number of successfully received PSDUs per STA (including PSDUs not addresse...
void MacRxTrace(std::string context, Ptr< const Packet > p)
MAC RX trace.
void PhyRxPayloadTrace(std::string context, WifiTxVector txVector, Time psduDuration)
PHY Rx trace.
std::map< Mac48Address, Time > timeLastTransmitted
Map that stores the time at which the last packet was transmitted per STA.
std::map< Mac48Address, Time > timeFirstTransmitted
Map that stores the time at which the first packet was transmitted per STA.
void PhyRxDropTrace(std::string context, Ptr< const Packet > p, WifiPhyRxfailureReason reason)
PHY Drop trace.
void BackoffTrace(std::string context, uint32_t newVal, uint8_t)
Backoff trace.
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition log.cc:279
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
double dBm_u
dBm weak type
Definition wifi-units.h:27
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:108
@ LOG_LEVEL_WARN
LOG_WARN and above.
Definition log.h:93
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:612
double degree_u
degree weak type (angle)
Definition wifi-units.h:35
double meter_u
meter weak type
Definition wifi-units.h:32
value
Definition second.py:37
wifi
Definition third.py:84
uint32_t bytesReceived
Counter of the received bytes.
bool verbose
MpduInfo structure.
Definition wifi-types.h:77
SignalNoiseDbm structure.
Definition wifi-types.h:70
std::ofstream throughput