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