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