A Discrete-Event Network Simulator
API
wifi-bianchi.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2012 The Boeing Company
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Gary Pei <guangyu.pei@boeing.com>
19  *
20  * Updated by Tom Henderson, Rohan Patidar, Hao Yin and S├ębastien Deronne
21  */
22 
23 // This program conducts a Bianchi analysis of a wifi network.
24 // Bianchi analysis involves saturating the network and observing how
25 // the maximum achievable throughput is governed by the DCF or ECDA
26 // channel access mechanisms. This program offers many configurable
27 // options, traces, and a validation option; the main output is a Gnuplot
28 // plot file plotting throughput vs. number of nodes.
29 
30 #include <fstream>
31 #include "ns3/log.h"
32 #include "ns3/config.h"
33 #include "ns3/gnuplot.h"
34 #include "ns3/boolean.h"
35 #include "ns3/string.h"
36 #include "ns3/double.h"
37 #include "ns3/integer.h"
38 #include "ns3/uinteger.h"
39 #include "ns3/command-line.h"
40 #include "ns3/node-list.h"
41 #include "ns3/yans-wifi-helper.h"
42 #include "ns3/ssid.h"
43 #include "ns3/wifi-mac-header.h"
44 #include "ns3/queue-size.h"
45 #include "ns3/propagation-loss-model.h"
46 #include "ns3/propagation-delay-model.h"
47 #include "ns3/rng-seed-manager.h"
48 #include "ns3/mobility-helper.h"
49 #include "ns3/wifi-net-device.h"
50 #include "ns3/packet-socket-helper.h"
51 #include "ns3/packet-socket-client.h"
52 #include "ns3/packet-socket-server.h"
53 #include "ns3/application-container.h"
54 #include "ns3/ampdu-subframe-header.h"
55 #include "ns3/wifi-mac.h"
56 
57 #define PI 3.1415926535
58 
59 NS_LOG_COMPONENT_DEFINE ("WifiBianchi");
60 
61 using namespace ns3;
62 
63 std::ofstream cwTraceFile;
64 std::ofstream backoffTraceFile;
65 std::ofstream phyTxTraceFile;
66 std::ofstream macTxTraceFile;
67 std::ofstream macRxTraceFile;
68 std::ofstream socketSendTraceFile;
69 
70 std::map<Mac48Address, uint64_t> packetsReceived;
71 std::map<Mac48Address, uint64_t> bytesReceived;
72 std::map<Mac48Address, uint64_t> packetsTransmitted;
73 std::map<Mac48Address, uint64_t> psduFailed;
74 std::map<Mac48Address, uint64_t> psduSucceeded;
75 std::map<Mac48Address, uint64_t> phyHeaderFailed;
76 std::map<Mac48Address, uint64_t> rxEventWhileTxing;
77 std::map<Mac48Address, uint64_t> rxEventWhileRxing;
78 std::map<Mac48Address, uint64_t> rxEventWhileDecodingPreamble;
79 std::map<Mac48Address, uint64_t> rxEventAbortedByTx;
80 
81 std::map<Mac48Address, Time> timeFirstReceived;
82 std::map<Mac48Address, Time> timeLastReceived;
83 std::map<Mac48Address, Time> timeFirstTransmitted;
84 std::map<Mac48Address, Time> timeLastTransmitted;
85 
86 std::set<uint32_t> associated;
87 
88 bool tracing = false;
89 uint32_t pktSize = 1500;
90 uint8_t maxMpdus = 0;
91 
92 std::map<std::string /* mode */, std::map<unsigned int /* number of nodes */, double /* calculated throughput */> > bianchiResultsEifs =
93 {
94 /* 11b */
95  {"DsssRate1Mbps", {
96  {5, 0.8418}, {10, 0.7831}, {15, 0.7460}, {20, 0.7186}, {25, 0.6973}, {30, 0.6802}, {35, 0.6639}, {40, 0.6501}, {45, 0.6386}, {50, 0.6285},
97  }},
98  {"DsssRate2Mbps", {
99  {5, 1.6170}, {10, 1.5075}, {15, 1.4371}, {20, 1.3849}, {25, 1.3442}, {30, 1.3115}, {35, 1.2803}, {40, 1.2538}, {45, 1.2317}, {50, 1.2124},
100  }},
101  {"DsssRate5_5Mbps", {
102  {5, 3.8565}, {10, 3.6170}, {15, 3.4554}, {20, 3.3339}, {25, 3.2385}, {30, 3.1613}, {35, 3.0878}, {40, 3.0249}, {45, 2.9725}, {50, 2.9266},
103  }},
104  {"DsssRate11Mbps", {
105  {5, 6.3821}, {10, 6.0269}, {15, 5.7718}, {20, 5.5765}, {25, 5.4217}, {30, 5.2958}, {35, 5.1755}, {40, 5.0722}, {45, 4.9860}, {50, 4.9103},
106  }},
107 /* 11a */
108  {"OfdmRate6Mbps", {
109  {5, 4.6899}, {10, 4.3197}, {15, 4.1107}, {20, 3.9589}, {25, 3.8478}, {30, 3.7490}, {35, 3.6618}, {40, 3.5927}, {45, 3.5358}, {50, 3.4711},
110  }},
111  {"OfdmRate9Mbps", {
112  {5, 6.8188}, {10, 6.2885}, {15, 5.9874}, {20, 5.7680}, {25, 5.6073}, {30, 5.4642}, {35, 5.3378}, {40, 5.2376}, {45, 5.1551}, {50, 5.0612},
113  }},
114  {"OfdmRate12Mbps", {
115  {5, 8.8972}, {10, 8.2154}, {15, 7.8259}, {20, 7.5415}, {25, 7.3329}, {30, 7.1469}, {35, 6.9825}, {40, 6.8521}, {45, 6.7447}, {50, 6.6225},
116  }},
117  {"OfdmRate18Mbps", {
118  {5, 12.6719}, {10, 11.7273}, {15, 11.1814}, {20, 10.7810}, {25, 10.4866}, {30, 10.2237}, {35, 9.9910}, {40, 9.8061}, {45, 9.6538}, {50, 9.4804},
119  }},
120  {"OfdmRate24Mbps", {
121  {5, 16.0836}, {10, 14.9153}, {15, 14.2327}, {20, 13.7300}, {25, 13.3595}, {30, 13.0281}, {35, 12.7343}, {40, 12.5008}, {45, 12.3083}, {50, 12.0889},
122  }},
123  {"OfdmRate36Mbps", {
124  {5, 22.0092}, {10, 20.4836}, {15, 19.5743}, {20, 18.8997}, {25, 18.4002}, {30, 17.9524}, {35, 17.5545}, {40, 17.2377}, {45, 16.9760}, {50, 16.6777},
125  }},
126  {"OfdmRate48Mbps", {
127  {5, 26.8382}, {10, 25.0509}, {15, 23.9672}, {20, 23.1581}, {25, 22.5568}, {30, 22.0165}, {35, 21.5355}, {40, 21.1519}, {45, 20.8348}, {50, 20.4729},
128  }},
129  {"OfdmRate54Mbps", {
130  {5, 29.2861}, {10, 27.3763}, {15, 26.2078}, {20, 25.3325}, {25, 24.6808}, {30, 24.0944}, {35, 23.5719}, {40, 23.1549}, {45, 22.8100}, {50, 22.4162},
131  }},
132 /* 11g */
133  {"ErpOfdmRate6Mbps", {
134  {5, 4.6899}, {10, 4.3197}, {15, 4.1107}, {20, 3.9589}, {25, 3.8478}, {30, 3.7490}, {35, 3.6618}, {40, 3.5927}, {45, 3.5358}, {50, 3.4711},
135  }},
136  {"ErpOfdmRate9Mbps", {
137  {5, 6.8188}, {10, 6.2885}, {15, 5.9874}, {20, 5.7680}, {25, 5.6073}, {30, 5.4642}, {35, 5.3378}, {40, 5.2376}, {45, 5.1551}, {50, 5.0612},
138  }},
139  {"ErpOfdmRate12Mbps", {
140  {5, 8.8972}, {10, 8.2154}, {15, 7.8259}, {20, 7.5415}, {25, 7.3329}, {30, 7.1469}, {35, 6.9825}, {40, 6.8521}, {45, 6.7447}, {50, 6.6225},
141  }},
142  {"ErpOfdmRate18Mbps", {
143  {5, 12.6719}, {10, 11.7273}, {15, 11.1814}, {20, 10.7810}, {25, 10.4866}, {30, 10.2237}, {35, 9.9910}, {40, 9.8061}, {45, 9.6538}, {50, 9.4804},
144  }},
145  {"ErpOfdmRate24Mbps", {
146  {5, 16.0836}, {10, 14.9153}, {15, 14.2327}, {20, 13.7300}, {25, 13.3595}, {30, 13.0281}, {35, 12.7343}, {40, 12.5008}, {45, 12.3083}, {50, 12.0889},
147  }},
148  {"ErpOfdmRate36Mbps", {
149  {5, 22.0092}, {10, 20.4836}, {15, 19.5743}, {20, 18.8997}, {25, 18.4002}, {30, 17.9524}, {35, 17.5545}, {40, 17.2377}, {45, 16.9760}, {50, 16.6777},
150  }},
151  {"ErpOfdmRate48Mbps", {
152  {5, 26.8382}, {10, 25.0509}, {15, 23.9672}, {20, 23.1581}, {25, 22.5568}, {30, 22.0165}, {35, 21.5355}, {40, 21.1519}, {45, 20.8348}, {50, 20.4729},
153  }},
154  {"ErpOfdmRate54Mbps", {
155  {5, 29.2861}, {10, 27.3763}, {15, 26.2078}, {20, 25.3325}, {25, 24.6808}, {30, 24.0944}, {35, 23.5719}, {40, 23.1549}, {45, 22.8100}, {50, 22.4162},
156  }},
157 /* 11ax, no frame aggregation */
158  {"HeMcs0_20MHz", {
159  {5, 6.3381}, {10, 5.8172}, {15, 5.5223}, {20, 5.3146}, {25, 5.1525}, {30, 5.0187}, {35, 4.9039}, {40, 4.8034}, {45, 4.7134}, {50, 4.6317},
160  }},
161  {"HeMcs1_20MHz", {
162  {5, 11.6580}, {10, 10.7369}, {15, 10.2068}, {20, 9.8309}, {25, 9.5365}, {30, 9.2930}, {35, 9.0837}, {40, 8.9001}, {45, 8.7355}, {50, 8.5860},
163  }},
164  {"HeMcs2_20MHz", {
165  {5, 15.8572}, {10, 14.6445}, {15, 13.9367}, {20, 13.4323}, {25, 13.0361}, {30, 12.7076}, {35, 12.4249}, {40, 12.1766}, {45, 11.9538}, {50, 11.7511},
166  }},
167  {"HeMcs3_20MHz", {
168  {5, 19.7457}, {10, 18.2820}, {15, 17.4163}, {20, 16.7963}, {25, 16.3078}, {30, 15.9021}, {35, 15.5524}, {40, 15.2449}, {45, 14.9687}, {50, 14.7173},
169  }},
170  {"HeMcs4_20MHz", {
171  {5, 25.8947}, {10, 24.0721}, {15, 22.9698}, {20, 22.1738}, {25, 21.5437}, {30, 21.0186}, {35, 20.5650}, {40, 20.1654}, {45, 19.8059}, {50, 19.4784},
172  }},
173  {"HeMcs5_20MHz", {
174  {5, 30.0542}, {10, 28.0155}, {15, 26.7625}, {20, 25.8523}, {25, 25.1295}, {30, 24.5258}, {35, 24.0034}, {40, 23.5426}, {45, 23.1277}, {50, 22.7492},
175  }},
176  {"HeMcs6_20MHz", {
177  {5, 32.6789}, {10, 30.5150}, {15, 29.1708}, {20, 28.1907}, {25, 27.4107}, {30, 26.7583}, {35, 26.1931}, {40, 25.6941}, {45, 25.2446}, {50, 24.8343},
178  }},
179  {"HeMcs7_20MHz", {
180  {5, 34.1710}, {10, 31.9398}, {15, 30.5451}, {20, 29.5261}, {25, 28.7140}, {30, 28.0342}, {35, 27.4449}, {40, 26.9245}, {45, 26.4554}, {50, 26.0271},
181  }},
182  {"HeMcs8_20MHz", {
183  {5, 37.6051}, {10, 35.2296}, {15, 33.7228}, {20, 32.6160}, {25, 31.7314}, {30, 30.9895}, {35, 30.3455}, {40, 29.7760}, {45, 29.2623}, {50, 28.7929},
184  }},
185  {"HeMcs9_20MHz", {
186  {5, 39.5947}, {10, 37.1424}, {15, 35.5731}, {20, 34.4169}, {25, 33.4911}, {30, 32.7138}, {35, 32.0385}, {40, 31.4410}, {45, 30.9016}, {50, 30.4086},
187  }},
188  {"HeMcs10_20MHz", {
189  {5, 39.5947}, {10, 37.1424}, {15, 35.5731}, {20, 34.4169}, {25, 33.4911}, {30, 32.7138}, {35, 32.0385}, {40, 31.4410}, {45, 30.9016}, {50, 30.4086},
190  }},
191  {"HeMcs11_20MHz", {
192  {5, 41.8065}, {10, 39.2749}, {15, 37.6383}, {20, 36.4282}, {25, 35.4575}, {30, 34.6414}, {35, 33.9316}, {40, 33.3031}, {45, 32.7355}, {50, 32.2164},
193  }},
194  {"HeMcs0_40MHz", {
195  {5, 11.4999}, {10, 10.5902}, {15, 10.0669}, {20, 9.6960}, {25, 9.4055}, {30, 9.1652}, {35, 8.9587}, {40, 8.7775}, {45, 8.6151}, {50, 8.4676},
196  }},
197  {"HeMcs1_40MHz", {
198  {5, 19.5937}, {10, 18.1394}, {15, 17.2798}, {20, 16.6642}, {25, 16.1793}, {30, 15.7766}, {35, 15.4295}, {40, 15.1242}, {45, 14.8502}, {50, 14.6007},
199  }},
200  {"HeMcs2_40MHz", {
201  {5, 25.6338}, {10, 23.8255}, {15, 22.7329}, {20, 21.9442}, {25, 21.3200}, {30, 20.7999}, {35, 20.3506}, {40, 19.9549}, {45, 19.5990}, {50, 19.2746},
202  }},
203  {"HeMcs3_40MHz", {
204  {5, 30.0542}, {10, 28.0155}, {15, 26.7625}, {20, 25.8523}, {25, 25.1295}, {30, 24.5258}, {35, 24.0034}, {40, 23.5426}, {45, 23.1277}, {50, 22.7492},
205  }},
206  {"HeMcs4_40MHz", {
207  {5, 37.6051}, {10, 35.2296}, {15, 33.7228}, {20, 32.6160}, {25, 31.7314}, {30, 30.9895}, {35, 30.3455}, {40, 29.7760}, {45, 29.2623}, {50, 28.7929},
208  }},
209  {"HeMcs5_40MHz", {
210  {5, 41.8065}, {10, 39.2749}, {15, 37.6383}, {20, 36.4282}, {25, 35.4575}, {30, 34.6414}, {35, 33.9316}, {40, 33.3031}, {45, 32.7355}, {50, 32.2164},
211  }},
212  {"HeMcs6_40MHz", {
213  {5, 44.2801}, {10, 41.6672}, {15, 39.9580}, {20, 38.6892}, {25, 37.6692}, {30, 36.8103}, {35, 36.0625}, {40, 35.3998}, {45, 34.8008}, {50, 34.2528},
214  }},
215  {"HeMcs7_40MHz", {
216  {5, 44.2801}, {10, 41.6672}, {15, 39.9580}, {20, 38.6892}, {25, 37.6692}, {30, 36.8103}, {35, 36.0625}, {40, 35.3998}, {45, 34.8008}, {50, 34.2528},
217  }},
218  {"HeMcs8_40MHz", {
219  {5, 47.0648}, {10, 44.3699}, {15, 42.5825}, {20, 41.2495}, {25, 40.1751}, {30, 39.2689}, {35, 38.4790}, {40, 37.7781}, {45, 37.1443}, {50, 36.5639},
220  }},
221  {"HeMcs9_40MHz", {
222  {5, 50.2233}, {10, 47.4474}, {15, 45.5760}, {20, 44.1727}, {25, 43.0382}, {30, 42.0794}, {35, 41.2425}, {40, 40.4991}, {45, 39.8262}, {50, 39.2095},
223  }},
224  {"HeMcs10_40MHz", {
225  {5, 50.2233}, {10, 47.4474}, {15, 45.5760}, {20, 44.1727}, {25, 43.0382}, {30, 42.0794}, {35, 41.2425}, {40, 40.4991}, {45, 39.8262}, {50, 39.2095},
226  }},
227  {"HeMcs11_40MHz", {
228  {5, 50.2233}, {10, 47.4474}, {15, 45.5760}, {20, 44.1727}, {25, 43.0382}, {30, 42.0794}, {35, 41.2425}, {40, 40.4991}, {45, 39.8262}, {50, 39.2095},
229  }},
230  {"HeMcs0_80MHz", {
231  {5, 19.6542}, {10, 18.1962}, {15, 17.3342}, {20, 16.7168}, {25, 16.2305}, {30, 15.8265}, {35, 15.4784}, {40, 15.1723}, {45, 14.8973}, {50, 14.6471},
232  }},
233  {"HeMcs1_80MHz", {
234  {5, 30.9311}, {10, 28.8495}, {15, 27.5657}, {20, 26.6320}, {25, 25.8899}, {30, 25.2699}, {35, 24.7332}, {40, 24.2595}, {45, 23.8330}, {50, 23.4439},
235  }},
236  {"HeMcs2_80MHz", {
237  {5, 37.0575}, {10, 34.7039}, {15, 33.2146}, {20, 32.1216}, {25, 31.2485}, {30, 30.5164}, {35, 29.8811}, {40, 29.3194}, {45, 28.8127}, {50, 28.3499},
238  }},
239  {"HeMcs3_80MHz", {
240  {5, 41.8065}, {10, 39.2749}, {15, 37.6383}, {20, 36.4282}, {25, 35.4575}, {30, 34.6414}, {35, 33.9316}, {40, 33.3031}, {45, 32.7355}, {50, 32.2164},
241  }},
242  {"HeMcs4_80MHz", {
243  {5, 47.0648}, {10, 44.3699}, {15, 42.5825}, {20, 41.2495}, {25, 40.1751}, {30, 39.2689}, {35, 38.4790}, {40, 37.7781}, {45, 37.1443}, {50, 36.5639},
244  }},
245  {"HeMcs5_80MHz", {
246  {5, 50.2233}, {10, 47.4474}, {15, 45.5760}, {20, 44.1727}, {25, 43.0382}, {30, 42.0794}, {35, 41.2425}, {40, 40.4991}, {45, 39.8262}, {50, 39.2095},
247  }},
248  {"HeMcs6_80MHz", {
249  {5, 53.8362}, {10, 50.9837}, {15, 49.0221}, {20, 47.5418}, {25, 46.3407}, {30, 45.3233}, {35, 44.4337}, {40, 43.6425}, {45, 42.9255}, {50, 42.2678},
250  }},
251  {"HeMcs7_80MHz", {
252  {5, 53.8362}, {10, 50.9837}, {15, 49.0221}, {20, 47.5418}, {25, 46.3407}, {30, 45.3233}, {35, 44.4337}, {40, 43.6425}, {45, 42.9255}, {50, 42.2678},
253  }},
254  {"HeMcs8_80MHz", {
255  {5, 53.8362}, {10, 50.9837}, {15, 49.0221}, {20, 47.5418}, {25, 46.3407}, {30, 45.3233}, {35, 44.4337}, {40, 43.6425}, {45, 42.9255}, {50, 42.2678},
256  }},
257  {"HeMcs9_80MHz", {
258  {5, 58.0092}, {10, 55.0896}, {15, 53.0321}, {20, 51.4672}, {25, 50.1922}, {30, 49.1091}, {35, 48.1601}, {40, 47.3148}, {45, 46.5478}, {50, 45.8436},
259  }},
260  {"HeMcs10_80MHz", {
261  {5, 58.0092}, {10, 55.0896}, {15, 53.0321}, {20, 51.4672}, {25, 50.1922}, {30, 49.1091}, {35, 48.1601}, {40, 47.3148}, {45, 46.5478}, {50, 45.8436},
262  }},
263  {"HeMcs11_80MHz", {
264  {5, 58.0092}, {10, 55.0896}, {15, 53.0321}, {20, 51.4672}, {25, 50.1922}, {30, 49.1091}, {35, 48.1601}, {40, 47.3148}, {45, 46.5478}, {50, 45.8436},
265  }},
266  {"HeMcs0_160MHz", {
267  {5, 29.8428}, {10, 27.8145}, {15, 26.5689}, {20, 25.6645}, {25, 24.9463}, {30, 24.3466}, {35, 23.8276}, {40, 23.3699}, {45, 22.9578}, {50, 22.5819},
268  }},
269  {"HeMcs1_160MHz", {
270  {5, 41.1308}, {10, 38.6227}, {15, 37.0064}, {20, 35.8126}, {25, 34.8556}, {30, 34.0513}, {35, 33.3520}, {40, 32.7329}, {45, 32.1739}, {50, 31.6628},
271  }},
272  {"HeMcs2_160MHz", {
273  {5, 46.2101}, {10, 43.5393}, {15, 41.7755}, {20, 40.4620}, {25, 39.4041}, {30, 38.5123}, {35, 37.7353}, {40, 37.0461}, {45, 36.4229}, {50, 35.8524},
274  }},
275  {"HeMcs3_160MHz", {
276  {5, 50.2233}, {10, 47.4474}, {15, 45.5760}, {20, 44.1727}, {25, 43.0382}, {30, 42.0794}, {35, 41.2425}, {40, 40.4991}, {45, 39.8262}, {50, 39.2095},
277  }},
278  {"HeMcs4_160MHz", {
279  {5, 53.8362}, {10, 50.9837}, {15, 49.0221}, {20, 47.5418}, {25, 46.3407}, {30, 45.3233}, {35, 44.4337}, {40, 43.6425}, {45, 42.9255}, {50, 42.2678},
280  }},
281  {"HeMcs5_160MHz", {
282  {5, 58.0092}, {10, 55.0896}, {15, 53.0321}, {20, 51.4672}, {25, 50.1922}, {30, 49.1091}, {35, 48.1601}, {40, 47.3148}, {45, 46.5478}, {50, 45.8436},
283  }},
284  {"HeMcs6_160MHz", {
285  {5, 58.0092}, {10, 55.0896}, {15, 53.0321}, {20, 51.4672}, {25, 50.1922}, {30, 49.1091}, {35, 48.1601}, {40, 47.3148}, {45, 46.5478}, {50, 45.8436},
286  }},
287  {"HeMcs7_160MHz", {
288  {5, 58.0092}, {10, 55.0896}, {15, 53.0321}, {20, 51.4672}, {25, 50.1922}, {30, 49.1091}, {35, 48.1601}, {40, 47.3148}, {45, 46.5478}, {50, 45.8436},
289  }},
290  {"HeMcs8_160MHz", {
291  {5, 58.0092}, {10, 55.0896}, {15, 53.0321}, {20, 51.4672}, {25, 50.1922}, {30, 49.1091}, {35, 48.1601}, {40, 47.3148}, {45, 46.5478}, {50, 45.8436},
292  }},
293  {"HeMcs9_160MHz", {
294  {5, 62.8834}, {10, 59.9147}, {15, 57.7564}, {20, 56.0992}, {25, 54.7419}, {30, 53.5850}, {35, 52.5689}, {40, 51.6620}, {45, 50.8379}, {50, 50.0803},
295  }},
296  {"HeMcs10_160MHz", {
297  {5, 62.8834}, {10, 59.9147}, {15, 57.7564}, {20, 56.0992}, {25, 54.7419}, {30, 53.5850}, {35, 52.5689}, {40, 51.6620}, {45, 50.8379}, {50, 50.0803},
298  }},
299  {"HeMcs11_160MHz", {
300  {5, 62.8834}, {10, 59.9147}, {15, 57.7564}, {20, 56.0992}, {25, 54.7419}, {30, 53.5850}, {35, 52.5689}, {40, 51.6620}, {45, 50.8379}, {50, 50.0803},
301  }},
302 };
303 
304 std::map<std::string /* mode */, std::map<unsigned int /* number of nodes */, double /* calculated throughput */> > bianchiResultsDifs =
305 {
306 /* 11b */
307  {"DsssRate1Mbps", {
308  {5, 0.8437}, {10, 0.7861}, {15, 0.7496}, {20, 0.7226}, {25, 0.7016}, {30, 0.6847}, {35, 0.6686}, {40, 0.6549}, {45, 0.6435}, {50, 0.6336},
309  }},
310  {"DsssRate2Mbps", {
311  {5, 1.6228}, {10, 1.5168}, {15, 1.4482}, {20, 1.3972}, {25, 1.3574}, {30, 1.3253}, {35, 1.2947}, {40, 1.2687}, {45, 1.2469}, {50, 1.2279},
312  }},
313  {"DsssRate5_5Mbps", {
314  {5, 3.8896}, {10, 3.6707}, {15, 3.5203}, {20, 3.4063}, {25, 3.3161}, {30, 3.2429}, {35, 3.1729}, {40, 3.1128}, {45, 3.0625}, {50, 3.0184},
315  }},
316  {"DsssRate11Mbps", {
317  {5, 6.4734}, {10, 6.1774}, {15, 5.9553}, {20, 5.7819}, {25, 5.6429}, {30, 5.5289}, {35, 5.4191}, {40, 5.3243}, {45, 5.2446}, {50, 5.1745},
318  }},
319 /* 11a */
320  {"OfdmRate6Mbps", {
321  {5, 4.7087}, {10, 4.3453}, {15, 4.1397}, {20, 3.9899}, {25, 3.8802}, {30, 3.7824}, {35, 3.6961}, {40, 3.6276}, {45, 3.5712}, {50, 3.5071},
322  }},
323  {"OfdmRate9Mbps", {
324  {5, 6.8586}, {10, 6.3431}, {15, 6.0489}, {20, 5.8340}, {25, 5.6762}, {30, 5.5355}, {35, 5.4110}, {40, 5.3122}, {45, 5.2307}, {50, 5.1380},
325  }},
326  {"OfdmRate12Mbps", {
327  {5, 8.9515}, {10, 8.2901}, {15, 7.9102}, {20, 7.6319}, {25, 7.4274}, {30, 7.2447}, {35, 7.0829}, {40, 6.9544}, {45, 6.8485}, {50, 6.7278},
328  }},
329  {"OfdmRate18Mbps", {
330  {5, 12.7822}, {10, 11.8801}, {15, 11.3543}, {20, 10.9668}, {25, 10.6809}, {30, 10.4249}, {35, 10.1978}, {40, 10.0171}, {45, 9.8679}, {50, 9.6978},
331  }},
332  {"OfdmRate24Mbps", {
333  {5, 16.2470}, {10, 15.1426}, {15, 14.4904}, {20, 14.0072}, {25, 13.6496}, {30, 13.3288}, {35, 13.0436}, {40, 12.8164}, {45, 12.6286}, {50, 12.4144},
334  }},
335  {"OfdmRate36Mbps", {
336  {5, 22.3164}, {10, 20.9147}, {15, 20.0649}, {20, 19.4289}, {25, 18.9552}, {30, 18.5284}, {35, 18.1476}, {40, 17.8434}, {45, 17.5915}, {50, 17.3036},
337  }},
338  {"OfdmRate48Mbps", {
339  {5, 27.2963}, {10, 25.6987}, {15, 24.7069}, {20, 23.9578}, {25, 23.3965}, {30, 22.8891}, {35, 22.4350}, {40, 22.0713}, {45, 21.7696}, {50, 21.4243},
340  }},
341  {"OfdmRate54Mbps", {
342  {5, 29.8324}, {10, 28.1519}, {15, 27.0948}, {20, 26.2925}, {25, 25.6896}, {30, 25.1434}, {35, 24.6539}, {40, 24.2613}, {45, 23.9353}, {50, 23.5618},
343  }},
344 /* 11g */
345  {"ErpOfdmRate6Mbps", {
346  {5, 4.7087}, {10, 4.3453}, {15, 4.1397}, {20, 3.9899}, {25, 3.8802}, {30, 3.7824}, {35, 3.6961}, {40, 3.6276}, {45, 3.5712}, {50, 3.5071},
347  }},
348  {"ErpOfdmRate9Mbps", {
349  {5, 6.8586}, {10, 6.3431}, {15, 6.0489}, {20, 5.8340}, {25, 5.6762}, {30, 5.5355}, {35, 5.4110}, {40, 5.3122}, {45, 5.2307}, {50, 5.1380},
350  }},
351  {"ErpOfdmRate12Mbps", {
352  {5, 8.9515}, {10, 8.2901}, {15, 7.9102}, {20, 7.6319}, {25, 7.4274}, {30, 7.2447}, {35, 7.0829}, {40, 6.9544}, {45, 6.8485}, {50, 6.7278},
353  }},
354  {"ErpOfdmRate18Mbps", {
355  {5, 12.7822}, {10, 11.8801}, {15, 11.3543}, {20, 10.9668}, {25, 10.6809}, {30, 10.4249}, {35, 10.1978}, {40, 10.0171}, {45, 9.8679}, {50, 9.6978},
356  }},
357  {"ErpOfdmRate24Mbps", {
358  {5, 16.2470}, {10, 15.1426}, {15, 14.4904}, {20, 14.0072}, {25, 13.6496}, {30, 13.3288}, {35, 13.0436}, {40, 12.8164}, {45, 12.6286}, {50, 12.4144},
359  }},
360  {"ErpOfdmRate36Mbps", {
361  {5, 22.3164}, {10, 20.9147}, {15, 20.0649}, {20, 19.4289}, {25, 18.9552}, {30, 18.5284}, {35, 18.1476}, {40, 17.8434}, {45, 17.5915}, {50, 17.3036},
362  }},
363  {"ErpOfdmRate48Mbps", {
364  {5, 27.2963}, {10, 25.6987}, {15, 24.7069}, {20, 23.9578}, {25, 23.3965}, {30, 22.8891}, {35, 22.4350}, {40, 22.0713}, {45, 21.7696}, {50, 21.4243},
365  }},
366  {"ErpOfdmRate54Mbps", {
367  {5, 29.8324}, {10, 28.1519}, {15, 27.0948}, {20, 26.2925}, {25, 25.6896}, {30, 25.1434}, {35, 24.6539}, {40, 24.2613}, {45, 23.9353}, {50, 23.5618},
368  }},
369 /* 11ax, no frame aggregation */
370  {"HeMcs0_20MHz", {
371  {5, 6.3746}, {10, 5.8670}, {15, 5.5782}, {20, 5.3742}, {25, 5.2147}, {30, 5.0829}, {35, 4.9696}, {40, 4.8703}, {45, 4.7813}, {50, 4.7004},
372  }},
373  {"HeMcs1_20MHz", {
374  {5, 11.7574}, {10, 10.8735}, {15, 10.3606}, {20, 9.9954}, {25, 9.7084}, {30, 9.4704}, {35, 9.2654}, {40, 9.0853}, {45, 8.9235}, {50, 8.7763},
375  }},
376  {"HeMcs2_20MHz", {
377  {5, 16.0419}, {10, 14.8998}, {15, 14.2252}, {20, 13.7413}, {25, 13.3594}, {30, 13.0417}, {35, 12.7674}, {40, 12.5258}, {45, 12.3086}, {50, 12.1107},
378  }},
379  {"HeMcs3_20MHz", {
380  {5, 20.0089}, {10, 18.6480}, {15, 17.8309}, {20, 17.2410}, {25, 16.7736}, {30, 16.3837}, {35, 16.0465}, {40, 15.7491}, {45, 15.4813}, {50, 15.2369},
381  }},
382  {"HeMcs4_20MHz", {
383  {5, 26.3492}, {10, 24.7107}, {15, 23.6964}, {20, 22.9553}, {25, 22.3640}, {30, 21.8683}, {35, 21.4379}, {40, 21.0571}, {45, 20.7134}, {50, 20.3991},
384  }},
385  {"HeMcs5_20MHz", {
386  {5, 30.6683}, {10, 28.8843}, {15, 27.7540}, {20, 26.9210}, {25, 26.2528}, {30, 25.6906}, {35, 25.2012}, {40, 24.7671}, {45, 24.3746}, {50, 24.0151},
387  }},
388  {"HeMcs6_20MHz", {
389  {5, 33.4062}, {10, 31.5485}, {15, 30.3527}, {20, 29.4662}, {25, 28.7527}, {30, 28.1508}, {35, 27.6259}, {40, 27.1597}, {45, 26.7376}, {50, 26.3507},
390  }},
391  {"HeMcs7_20MHz", {
392  {5, 34.9671}, {10, 33.0739}, {15, 31.8436}, {20, 30.9282}, {25, 30.1900}, {30, 29.5665}, {35, 29.0221}, {40, 28.5382}, {45, 28.0997}, {50, 27.6975},
393  }},
394  {"HeMcs8_20MHz", {
395  {5, 38.5714}, {10, 36.6144}, {15, 35.3124}, {20, 34.3355}, {25, 33.5438}, {30, 32.8728}, {35, 32.2854}, {40, 31.7623}, {45, 31.2874}, {50, 30.8512},
396  }},
397  {"HeMcs9_20MHz", {
398  {5, 40.6674}, {10, 38.6851}, {15, 37.3466}, {20, 36.3371}, {25, 35.5165}, {30, 34.8197}, {35, 34.2087}, {40, 33.6638}, {45, 33.1688}, {50, 32.7137},
399  }},
400  {"HeMcs10_20MHz", {
401  {5, 40.6674}, {10, 38.6851}, {15, 37.3466}, {20, 36.3371}, {25, 35.5165}, {30, 34.8197}, {35, 34.2087}, {40, 33.6638}, {45, 33.1688}, {50, 32.7137},
402  }},
403  {"HeMcs11_20MHz", {
404  {5, 43.0043}, {10, 41.0039}, {15, 39.6294}, {20, 38.5865}, {25, 37.7358}, {30, 37.0116}, {35, 36.3756}, {40, 35.8076}, {45, 35.2909}, {50, 34.8154},
405  }},
406  {"HeMcs0_40MHz", {
407  {5, 11.6208}, {10, 10.7566}, {15, 10.2544}, {20, 9.8965}, {25, 9.6151}, {30, 9.3815}, {35, 9.1804}, {40, 9.0035}, {45, 8.8446}, {50, 8.7000},
408  }},
409  {"HeMcs1_40MHz", {
410  {5, 19.8764}, {10, 18.5328}, {15, 17.7255}, {20, 17.1424}, {25, 16.6803}, {30, 16.2947}, {35, 15.9612}, {40, 15.6668}, {45, 15.4018}, {50, 15.1599},
411  }},
412  {"HeMcs2_40MHz", {
413  {5, 26.1198}, {10, 24.5088}, {15, 23.5107}, {20, 22.7810}, {25, 22.1986}, {30, 21.7101}, {35, 21.2858}, {40, 20.9104}, {45, 20.5714}, {50, 20.2613},
414  }},
415  {"HeMcs3_40MHz", {
416  {5, 30.6683}, {10, 28.8843}, {15, 27.7540}, {20, 26.9210}, {25, 26.2528}, {30, 25.6906}, {35, 25.2012}, {40, 24.7671}, {45, 24.3746}, {50, 24.0151},
417  }},
418  {"HeMcs4_40MHz", {
419  {5, 38.5714}, {10, 36.6144}, {15, 35.3124}, {20, 34.3355}, {25, 33.5438}, {30, 32.8728}, {35, 32.2854}, {40, 31.7623}, {45, 31.2874}, {50, 30.8512},
420  }},
421  {"HeMcs5_40MHz", {
422  {5, 43.0043}, {10, 41.0039}, {15, 39.6294}, {20, 38.5865}, {25, 37.7358}, {30, 37.0116}, {35, 36.3756}, {40, 35.8076}, {45, 35.2909}, {50, 34.8154},
423  }},
424  {"HeMcs6_40MHz", {
425  {5, 45.6261}, {10, 43.6185}, {15, 42.2095}, {20, 41.1328}, {25, 40.2509}, {30, 39.4981}, {35, 38.8356}, {40, 38.2430}, {45, 37.7032}, {50, 37.2058},
426  }},
427  {"HeMcs7_40MHz", {
428  {5, 45.6261}, {10, 43.6185}, {15, 42.2095}, {20, 41.1328}, {25, 40.2509}, {30, 39.4981}, {35, 38.8356}, {40, 38.2430}, {45, 37.7032}, {50, 37.2058},
429  }},
430  {"HeMcs8_40MHz", {
431  {5, 48.5883}, {10, 46.5892}, {15, 45.1489}, {20, 44.0388}, {25, 43.1252}, {30, 42.3428}, {35, 41.6525}, {40, 41.0338}, {45, 40.4694}, {50, 39.9486},
432  }},
433  {"HeMcs9_40MHz", {
434  {5, 51.9619}, {10, 49.9941}, {15, 48.5284}, {20, 47.3867}, {25, 46.4416}, {30, 45.6290}, {35, 44.9099}, {40, 44.2640}, {45, 43.6736}, {50, 43.1279},
435  }},
436  {"HeMcs10_40MHz", {
437  {5, 51.9619}, {10, 49.9941}, {15, 48.5284}, {20, 47.3867}, {25, 46.4416}, {30, 45.6290}, {35, 44.9099}, {40, 44.2640}, {45, 43.6736}, {50, 43.1279},
438  }},
439  {"HeMcs11_40MHz", {
440  {5, 51.9619}, {10, 49.9941}, {15, 48.5284}, {20, 47.3867}, {25, 46.4416}, {30, 45.6290}, {35, 44.9099}, {40, 44.2640}, {45, 43.6736}, {50, 43.1279},
441  }},
442  {"HeMcs0_80MHz", {
443  {5, 20.0101}, {10, 18.6928}, {15, 17.8976}, {20, 17.3219}, {25, 16.8648}, {30, 16.4830}, {35, 16.1523}, {40, 15.8603}, {45, 15.5971}, {50, 15.3567},
444  }},
445  {"HeMcs1_80MHz", {
446  {5, 31.6415}, {10, 29.8575}, {15, 28.7177}, {20, 27.8747}, {25, 27.1971}, {30, 26.6261}, {35, 26.1283}, {40, 25.6865}, {45, 25.2866}, {50, 24.9200},
447  }},
448  {"HeMcs2_80MHz", {
449  {5, 38.0818}, {10, 36.1730}, {15, 34.9016}, {20, 33.9470}, {25, 33.1729}, {30, 32.5165}, {35, 31.9417}, {40, 31.4295}, {45, 30.9645}, {50, 30.5372},
450  }},
451  {"HeMcs3_80MHz", {
452  {5, 43.0043}, {10, 41.0039}, {15, 39.6294}, {20, 38.5865}, {25, 37.7358}, {30, 37.0116}, {35, 36.3756}, {40, 35.8076}, {45, 35.2909}, {50, 34.8154},
453  }},
454  {"HeMcs4_80MHz", {
455  {5, 48.5883}, {10, 46.5892}, {15, 45.1489}, {20, 44.0388}, {25, 43.1252}, {30, 42.3428}, {35, 41.6525}, {40, 41.0338}, {45, 40.4694}, {50, 39.9486},
456  }},
457  {"HeMcs5_80MHz", {
458  {5, 51.9619}, {10, 49.9941}, {15, 48.5284}, {20, 47.3867}, {25, 46.4416}, {30, 45.6290}, {35, 44.9099}, {40, 44.2640}, {45, 43.6736}, {50, 43.1279},
459  }},
460  {"HeMcs6_80MHz", {
461  {5, 55.8389}, {10, 53.9360}, {15, 52.4548}, {20, 51.2855}, {25, 50.3106}, {30, 49.4682}, {35, 48.7201}, {40, 48.0462}, {45, 47.4288}, {50, 46.8571},
462  }},
463  {"HeMcs7_80MHz", {
464  {5, 55.8389}, {10, 53.9360}, {15, 52.4548}, {20, 51.2855}, {25, 50.3106}, {30, 49.4682}, {35, 48.7201}, {40, 48.0462}, {45, 47.4288}, {50, 46.8571},
465  }},
466  {"HeMcs8_80MHz", {
467  {5, 55.8389}, {10, 53.9360}, {15, 52.4548}, {20, 51.2855}, {25, 50.3106}, {30, 49.4682}, {35, 48.7201}, {40, 48.0462}, {45, 47.4288}, {50, 46.8571},
468  }},
469  {"HeMcs9_80MHz", {
470  {5, 60.3411}, {10, 58.5527}, {15, 57.0724}, {20, 55.8834}, {25, 54.8827}, {30, 54.0128}, {35, 53.2368}, {40, 52.5352}, {45, 51.8906}, {50, 51.2922},
471  }},
472  {"HeMcs10_80MHz", {
473  {5, 60.3411}, {10, 58.5527}, {15, 57.0724}, {20, 55.8834}, {25, 54.8827}, {30, 54.0128}, {35, 53.2368}, {40, 52.5352}, {45, 51.8906}, {50, 51.2922},
474  }},
475  {"HeMcs11_80MHz", {
476  {5, 60.3411}, {10, 58.5527}, {15, 57.0724}, {20, 55.8834}, {25, 54.8827}, {30, 54.0128}, {35, 53.2368}, {40, 52.5352}, {45, 51.8906}, {50, 51.2922},
477  }},
478  {"HeMcs0_160MHz", {
479  {5, 30.6710}, {10, 28.9919}, {15, 27.9160}, {20, 27.1188}, {25, 26.4770}, {30, 25.9355}, {35, 25.4630}, {40, 25.0432}, {45, 24.6629}, {50, 24.3141},
480  }},
481  {"HeMcs1_160MHz", {
482  {5, 42.3965}, {10, 40.4510}, {15, 39.1127}, {20, 38.0965}, {25, 37.2670}, {30, 36.5606}, {35, 35.9398}, {40, 35.3852}, {45, 34.8806}, {50, 34.4160},
483  }},
484  {"HeMcs2_160MHz", {
485  {5, 47.8139}, {10, 45.8767}, {15, 44.4795}, {20, 43.4017}, {25, 42.5141}, {30, 41.7535}, {35, 41.0821}, {40, 40.4801}, {45, 39.9307}, {50, 39.4236},
486  }},
487  {"HeMcs3_160MHz", {
488  {5, 51.9619}, {10, 49.9941}, {15, 48.5284}, {20, 47.3867}, {25, 46.4416}, {30, 45.6290}, {35, 44.9099}, {40, 44.2640}, {45, 43.6736}, {50, 43.1279},
489  }},
490  {"HeMcs4_160MHz", {
491  {5, 55.8389}, {10, 53.9360}, {15, 52.4548}, {20, 51.2855}, {25, 50.3106}, {30, 49.4682}, {35, 48.7201}, {40, 48.0462}, {45, 47.4288}, {50, 46.8571},
492  }},
493  {"HeMcs5_160MHz", {
494  {5, 60.3411}, {10, 58.5527}, {15, 57.0724}, {20, 55.8834}, {25, 54.8827}, {30, 54.0128}, {35, 53.2368}, {40, 52.5352}, {45, 51.8906}, {50, 51.2922},
495  }},
496  {"HeMcs6_160MHz", {
497  {5, 60.3411}, {10, 58.5527}, {15, 57.0724}, {20, 55.8834}, {25, 54.8827}, {30, 54.0128}, {35, 53.2368}, {40, 52.5352}, {45, 51.8906}, {50, 51.2922},
498  }},
499  {"HeMcs7_160MHz", {
500  {5, 60.3411}, {10, 58.5527}, {15, 57.0724}, {20, 55.8834}, {25, 54.8827}, {30, 54.0128}, {35, 53.2368}, {40, 52.5352}, {45, 51.8906}, {50, 51.2922},
501  }},
502  {"HeMcs8_160MHz", {
503  {5, 60.3411}, {10, 58.5527}, {15, 57.0724}, {20, 55.8834}, {25, 54.8827}, {30, 54.0128}, {35, 53.2368}, {40, 52.5352}, {45, 51.8906}, {50, 51.2922},
504  }},
505  {"HeMcs9_160MHz", {
506  {5, 65.6329}, {10, 64.0336}, {15, 62.5814}, {20, 61.3869}, {25, 60.3690}, {30, 59.4769}, {35, 58.6764}, {40, 57.9495}, {45, 57.2790}, {50, 56.6548},
507  }},
508  {"HeMcs10_160MHz", {
509  {5, 65.6329}, {10, 64.0336}, {15, 62.5814}, {20, 61.3869}, {25, 60.3690}, {30, 59.4769}, {35, 58.6764}, {40, 57.9495}, {45, 57.2790}, {50, 56.6548},
510  }},
511  {"HeMcs11_160MHz", {
512  {5, 65.6329}, {10, 64.0336}, {15, 62.5814}, {20, 61.3869}, {25, 60.3690}, {30, 59.4769}, {35, 58.6764}, {40, 57.9495}, {45, 57.2790}, {50, 56.6548},
513  }},
514 };
515 
516 // Parse context strings of the form "/NodeList/x/DeviceList/x/..." to extract the NodeId integer
517 uint32_t
518 ContextToNodeId (std::string context)
519 {
520  std::string sub = context.substr (10);
521  uint32_t pos = sub.find ("/Device");
522  return atoi (sub.substr (0, pos).c_str ());
523 }
524 
525 // Parse context strings of the form "/NodeList/x/DeviceList/x/..." and fetch the Mac address
527 ContextToMac (std::string context)
528 {
529  std::string sub = context.substr (10);
530  uint32_t pos = sub.find ("/Device");
531  uint32_t nodeId = atoi (sub.substr (0, pos).c_str ());
532  Ptr<Node> n = NodeList::GetNode (nodeId);
534  for (uint32_t i = 0; i < n->GetNDevices (); i++)
535  {
536  d = n->GetDevice (i)->GetObject<WifiNetDevice> ();
537  if (d)
538  {
539  break;
540  }
541  }
542  return Mac48Address::ConvertFrom (d->GetAddress ());
543 }
544 
545 // Functions for tracing.
546 
547 void
548 IncrementCounter (std::map<Mac48Address, uint64_t> & counter, Mac48Address addr, uint64_t increment = 1)
549 {
550  auto it = counter.find (addr);
551  if (it != counter.end ())
552  {
553  it->second += increment;
554  }
555  else
556  {
557  counter.insert (std::make_pair (addr, increment));
558  }
559 }
560 
561 void
562 TracePacketReception (std::string context, Ptr<const Packet> p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
563 {
564  Ptr<Packet> packet = p->Copy ();
565  if (txVector.IsAggregation ())
566  {
567  AmpduSubframeHeader subHdr;
568  uint32_t extractedLength;
569  packet->RemoveHeader (subHdr);
570  extractedLength = subHdr.GetLength ();
571  packet = packet->CreateFragment (0, static_cast<uint32_t> (extractedLength));
572  }
573  WifiMacHeader hdr;
574  packet->PeekHeader (hdr);
575  // hdr.GetAddr1() is the receiving MAC address
576  if (hdr.GetAddr1 () != ContextToMac (context))
577  {
578  return;
579  }
580  // hdr.GetAddr2() is the sending MAC address
581  if (packet->GetSize () >= pktSize) // ignore non-data frames
582  {
585  auto itTimeFirstReceived = timeFirstReceived.find (hdr.GetAddr2 ());
586  if (itTimeFirstReceived == timeFirstReceived.end ())
587  {
588  timeFirstReceived.insert (std::make_pair (hdr.GetAddr2 (), Simulator::Now ()));
589  }
590  auto itTimeLastReceived = timeLastReceived.find (hdr.GetAddr2 ());
591  if (itTimeLastReceived != timeLastReceived.end ())
592  {
593  itTimeLastReceived->second = Simulator::Now ();
594  }
595  else
596  {
597  timeLastReceived.insert (std::make_pair (hdr.GetAddr2 (), Simulator::Now ()));
598  }
599  }
600 }
601 
602 void
603 CwTrace (std::string context, uint32_t oldVal, uint32_t newVal)
604 {
605  NS_LOG_INFO ("CW time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " val=" << newVal);
606  if (tracing)
607  {
608  cwTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << newVal << std::endl;
609  }
610 }
611 
612 void
613 BackoffTrace (std::string context, uint32_t newVal)
614 {
615  NS_LOG_INFO ("Backoff time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " val=" << newVal);
616  if (tracing)
617  {
618  backoffTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << newVal << std::endl;
619  }
620 }
621 
622 void
624 {
625  NS_LOG_INFO ("PHY-RX-START time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize ());
626 }
627 
628 void
629 PhyRxPayloadTrace (std::string context, WifiTxVector txVector, Time psduDuration)
630 {
631  NS_LOG_INFO ("PHY-RX-PAYLOAD-START time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " psduDuration=" << psduDuration);
632 }
633 
634 void
636 {
637  NS_LOG_INFO ("PHY-RX-DROP time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize () << " reason=" << reason);
638  Mac48Address addr = ContextToMac (context);
639  switch (reason)
640  {
642  NS_FATAL_ERROR ("RX packet with unsupported settings!");
643  break;
644  case CHANNEL_SWITCHING:
645  NS_FATAL_ERROR ("Channel is switching!");
646  break;
648  {
649  if (p->GetSize () >= pktSize) // ignore non-data frames
650  {
652  }
653  break;
654  }
655  case RXING:
656  {
657  if (p->GetSize () >= pktSize) // ignore non-data frames
658  {
660  }
661  break;
662  }
663  case TXING:
664  {
665  if (p->GetSize () >= pktSize) // ignore non-data frames
666  {
668  }
669  break;
670  }
671  case SLEEPING:
672  NS_FATAL_ERROR ("Device is sleeping!");
673  break;
675  NS_FATAL_ERROR ("Preamble should always be detected!");
676  break;
678  {
679  if (p->GetSize () >= pktSize) // ignore non-data frames
680  {
682  }
683  break;
684  }
685  case L_SIG_FAILURE:
686  {
687  if (p->GetSize () >= pktSize) // ignore non-data frames
688  {
690  }
691  break;
692  }
693  case HT_SIG_FAILURE:
694  case SIG_A_FAILURE:
695  case SIG_B_FAILURE:
696  NS_FATAL_ERROR ("Unexpected PHY header failure!");
698  NS_FATAL_ERROR ("All devices should send with same power, so no packet switch during preamble detection should occur!");
699  break;
701  NS_FATAL_ERROR ("Frame capture should be disabled!");
702  break;
703  case OBSS_PD_CCA_RESET:
704  NS_FATAL_ERROR ("Unexpected CCA reset!");
705  break;
706  case UNKNOWN:
707  default:
708  NS_FATAL_ERROR ("Unknown drop reason!");
709  break;
710  }
711 }
712 
713 void
714 PhyRxDoneTrace (std::string context, Ptr<const Packet> p)
715 {
716  NS_LOG_INFO ("PHY-RX-END time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize ());
717 }
718 
719 void
720 PhyRxOkTrace (std::string context, Ptr<const Packet> p, double snr, WifiMode mode, WifiPreamble preamble)
721 {
722  uint8_t nMpdus = (p->GetSize () / pktSize);
723  NS_LOG_INFO ("PHY-RX-OK time=" << Simulator::Now ().As (Time::S)
724  << " node=" << ContextToNodeId (context)
725  << " size=" << p->GetSize ()
726  << " nMPDUs=" << +nMpdus
727  << " snr=" << snr
728  << " mode=" << mode
729  << " preamble=" << preamble);
730  if ((maxMpdus != 0) && (nMpdus != 0) && (nMpdus != maxMpdus))
731  {
732  if (nMpdus > maxMpdus)
733  {
734  NS_FATAL_ERROR ("A-MPDU settings not properly applied: maximum configured MPDUs is " << +maxMpdus << " but received an A-MPDU containing " << +nMpdus << " MPDUs");
735  }
736  NS_LOG_WARN ("Warning: less MPDUs aggregated in a received A-MPDU (" << +nMpdus << ") than configured (" << +maxMpdus << ")");
737  }
738  if (p->GetSize () >= pktSize) // ignore non-data frames
739  {
740  Mac48Address addr = ContextToMac (context);
742  }
743 }
744 
745 void
746 PhyRxErrorTrace (std::string context, Ptr<const Packet> p, double snr)
747 {
748  NS_LOG_INFO ("PHY-RX-ERROR time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize () << " snr=" << snr);
749  if (p->GetSize () >= pktSize) // ignore non-data frames
750  {
751  Mac48Address addr = ContextToMac (context);
753  }
754 }
755 
756 void
757 PhyTxTrace (std::string context, Ptr<const Packet> p, double txPowerW)
758 {
759  NS_LOG_INFO ("PHY-TX-START time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize () << " " << txPowerW);
760  if (tracing)
761  {
762  phyTxTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " size=" << p->GetSize () << " " << txPowerW << std::endl;
763  }
764  if (p->GetSize () >= pktSize) // ignore non-data frames
765  {
766  Mac48Address addr = ContextToMac (context);
768  }
769 }
770 
771 void
772 PhyTxDoneTrace (std::string context, Ptr<const Packet> p)
773 {
774  NS_LOG_INFO ("PHY-TX-END time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " " << p->GetSize ());
775 }
776 
777 void
778 MacTxTrace (std::string context, Ptr<const Packet> p)
779 {
780  if (tracing)
781  {
782  macTxTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << p->GetSize () << std::endl;
783  }
784 }
785 
786 void
787 MacRxTrace (std::string context, Ptr<const Packet> p)
788 {
789  if (tracing)
790  {
791  macRxTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << p->GetSize () << std::endl;
792  }
793 }
794 
795 void
796 SocketSendTrace (std::string context, Ptr<const Packet> p, const Address &addr)
797 {
798  if (tracing)
799  {
800  socketSendTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << p->GetSize () << " " << addr << std::endl;
801  }
802 }
803 
804 void
805 AssociationLog (std::string context, Mac48Address address)
806 {
807  uint32_t nodeId = ContextToNodeId (context);
808  auto it = associated.find (nodeId);
809  if (it == associated.end ())
810  {
811  NS_LOG_DEBUG ("Association: time=" << Simulator::Now () << " node=" << nodeId);
812  associated.insert (it, nodeId);
813  }
814  else
815  {
816  NS_FATAL_ERROR (nodeId << " is already associated!");
817  }
818 }
819 
820 void
821 DisassociationLog (std::string context, Mac48Address address)
822 {
823  uint32_t nodeId = ContextToNodeId (context);
824  NS_LOG_DEBUG ("Disassociation: time=" << Simulator::Now () << " node=" << nodeId);
825  NS_FATAL_ERROR ("Device should not disassociate!");
826 }
827 
828 void
830 {
831  bytesReceived.clear ();
832  packetsReceived.clear ();
833  packetsTransmitted.clear ();
834  psduFailed.clear ();
835  psduSucceeded.clear ();
836  phyHeaderFailed.clear ();
837  timeFirstReceived.clear ();
838  timeLastReceived.clear ();
840  rxEventWhileRxing.clear ();
841  rxEventWhileTxing.clear ();
842  rxEventAbortedByTx.clear ();
843 }
844 
845 class Experiment
846 {
847 public:
849 
869  int Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel,
870  uint32_t trialNumber, uint32_t networkSize, Time duration, bool pcap, bool infra, uint16_t guardIntervalNs,
871  double distanceM, double apTxPowerDbm, double staTxPowerDbm, Time pktInterval);
872 };
873 
875 {
876 }
877 
878 int
879 Experiment::Run (const WifiHelper &helper, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel,
880  uint32_t trialNumber, uint32_t networkSize, Time duration, bool pcap, bool infra, uint16_t guardIntervalNs,
881  double distance, double apTxPowerDbm, double staTxPowerDbm, Time pktInterval)
882 {
885 
886  NodeContainer wifiNodes;
887  if (infra)
888  {
889  wifiNodes.Create (networkSize + 1);
890  }
891  else
892  {
893  wifiNodes.Create (networkSize);
894  }
895 
896  YansWifiPhyHelper phy = wifiPhy;
897  phy.SetErrorRateModel ("ns3::NistErrorRateModel");
898  phy.SetChannel (wifiChannel.Create ());
899  phy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
900 
901  WifiMacHelper mac = wifiMac;
902  WifiHelper wifi = helper;
904  uint32_t nNodes = wifiNodes.GetN ();
905  if (infra)
906  {
907  Ssid ssid = Ssid ("wifi-bianchi");
908  uint64_t beaconInterval = std::min<uint64_t> ((ceil ((duration.GetSeconds () * 1000000) / 1024) * 1024), (65535 * 1024)); //beacon interval needs to be a multiple of time units (1024 us)
909  mac.SetType ("ns3::ApWifiMac",
910  "BeaconInterval", TimeValue (MicroSeconds (beaconInterval)),
911  "Ssid", SsidValue (ssid));
912  phy.Set ("TxPowerStart", DoubleValue (apTxPowerDbm));
913  phy.Set ("TxPowerEnd", DoubleValue (apTxPowerDbm));
914  devices = wifi.Install (phy, mac, wifiNodes.Get (0));
915 
916  mac.SetType ("ns3::StaWifiMac",
917  "MaxMissedBeacons", UintegerValue (std::numeric_limits<uint32_t>::max ()),
918  "Ssid", SsidValue (ssid));
919  phy.Set ("TxPowerStart", DoubleValue (staTxPowerDbm));
920  phy.Set ("TxPowerEnd", DoubleValue (staTxPowerDbm));
921  for (uint32_t i = 1; i < nNodes; ++i)
922  {
923  devices.Add (wifi.Install (phy, mac, wifiNodes.Get (i)));
924  }
925  }
926  else
927  {
928  mac.SetType ("ns3::AdhocWifiMac");
929  phy.Set ("TxPowerStart", DoubleValue (staTxPowerDbm));
930  phy.Set ("TxPowerEnd", DoubleValue (staTxPowerDbm));
931  devices = wifi.Install (phy, mac, wifiNodes);
932  }
933 
934  wifi.AssignStreams (devices, trialNumber);
935 
936  Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue (guardIntervalNs == 400));
937  Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HeConfiguration/GuardInterval", TimeValue (NanoSeconds (guardIntervalNs)));
938 
939  // Configure aggregation
940  for (uint32_t i = 0; i < nNodes; ++i)
941  {
942  Ptr<NetDevice> dev = wifiNodes.Get (i)->GetDevice (0);
943  Ptr<WifiNetDevice> wifi_dev = DynamicCast<WifiNetDevice> (dev);
944  wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
945  wifi_dev->GetMac ()->SetAttribute ("BK_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
946  wifi_dev->GetMac ()->SetAttribute ("VO_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
947  wifi_dev->GetMac ()->SetAttribute ("VI_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
948  }
949 
951  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
952  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
953  // Set postion for AP
954  positionAlloc->Add (Vector (1.0, 1.0, 0.0));
955 
956  // Set postion for STAs
957  double angle = (static_cast<double> (360) / (nNodes - 1));
958  for (uint32_t i = 0; i < (nNodes - 1); ++i)
959  {
960  positionAlloc->Add (Vector (1.0 + (distance * cos ((i * angle * PI) / 180)), 1.0 + (distance * sin ((i * angle * PI) / 180)), 0.0));
961  }
962 
963  mobility.SetPositionAllocator (positionAlloc);
964  mobility.Install (wifiNodes);
965 
966  PacketSocketHelper packetSocket;
967  packetSocket.Install (wifiNodes);
968 
970  Ptr<UniformRandomVariable> startTime = CreateObject<UniformRandomVariable> ();
971  startTime->SetAttribute ("Stream", IntegerValue (trialNumber));
972  startTime->SetAttribute ("Max", DoubleValue (5.0));
973 
974  uint32_t i = infra ? 1 : 0;
975  for (; i < nNodes; ++i)
976  {
977  uint32_t j = infra ? 0 : (i + 1) % nNodes;
978  PacketSocketAddress socketAddr;
979  socketAddr.SetSingleDevice (devices.Get (i)->GetIfIndex ());
980  socketAddr.SetPhysicalAddress (devices.Get (j)->GetAddress ());
981  socketAddr.SetProtocol (1);
982 
983  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
984  client->SetRemote (socketAddr);
985  wifiNodes.Get (i)->AddApplication (client);
986  client->SetAttribute ("PacketSize", UintegerValue (pktSize));
987  client->SetAttribute ("MaxPackets", UintegerValue (0));
988  client->SetAttribute ("Interval", TimeValue (pktInterval));
989  double start = startTime->GetValue ();
990  NS_LOG_DEBUG ("Client " << i << " starting at " << start);
991  client->SetStartTime (Seconds (start));
992 
993  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
994  server->SetLocal (socketAddr);
995  wifiNodes.Get (j)->AddApplication (server);
996  }
997 
998  // Log packet receptions
999  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx", MakeCallback (&TracePacketReception));
1000 
1001  // Log association and disassociation
1002  if (infra)
1003  {
1004  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc", MakeCallback (&AssociationLog));
1005  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/DeAssoc", MakeCallback (&DisassociationLog));
1006  }
1007 
1008  // Trace CW evolution
1009  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/Txop/CwTrace", MakeCallback (&CwTrace));
1010  // Trace backoff evolution
1011  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::WifiMac/Txop/BackoffTrace", MakeCallback (&BackoffTrace));
1012  // Trace PHY Tx start events
1013  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxBegin", MakeCallback (&PhyTxTrace));
1014  // Trace PHY Tx end events
1015  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxEnd", MakeCallback (&PhyTxDoneTrace));
1016  // Trace PHY Rx start events
1017  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin", MakeCallback (&PhyRxTrace));
1018  // Trace PHY Rx payload start events
1019  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxPayloadBegin", MakeCallback (&PhyRxPayloadTrace));
1020  // Trace PHY Rx drop events
1021  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxDrop", MakeCallback (&PhyRxDropTrace));
1022  // Trace PHY Rx end events
1023  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxEnd", MakeCallback (&PhyRxDoneTrace));
1024  // Trace PHY Rx error events
1025  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxError", MakeCallback (&PhyRxErrorTrace));
1026  // Trace PHY Rx success events
1027  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxOk", MakeCallback (&PhyRxOkTrace));
1028  // Trace packet transmission by the device
1029  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx", MakeCallback (&MacTxTrace));
1030  // Trace packet receptions to the device
1031  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx", MakeCallback (&MacRxTrace));
1032  // Trace packets transmitted by the application
1033  Config::Connect ("/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::PacketSocketClient/Tx", MakeCallback (&SocketSendTrace));
1034 
1036  Simulator::Stop (Seconds (10) + duration);
1037 
1038  if (pcap)
1039  {
1040  phy.EnablePcap ("wifi_bianchi_pcap", devices);
1041  }
1042 
1043  Simulator::Run ();
1044  Simulator::Destroy ();
1045 
1046  if (tracing)
1047  {
1048  cwTraceFile.flush ();
1049  backoffTraceFile.flush ();
1050  phyTxTraceFile.flush ();
1051  macTxTraceFile.flush ();
1052  macRxTraceFile.flush ();
1053  socketSendTraceFile.flush ();
1054  }
1055 
1056  return 0;
1057 }
1058 
1059 uint64_t
1060 GetCount (const std::map<Mac48Address, uint64_t> & counter, Mac48Address addr)
1061 {
1062  uint64_t count = 0;
1063  auto it = counter.find (addr);
1064  if (it != counter.end ())
1065  {
1066  count = it->second;
1067  }
1068  return count;
1069 }
1070 
1071 int main (int argc, char *argv[])
1072 {
1073  uint32_t nMinStas = 5;
1074  uint32_t nMaxStas = 50;
1075  uint32_t nStepSize = 5;
1076  uint32_t verbose = 0;
1077  double duration = 100;
1078  uint32_t trials = 1;
1079  bool pcap = false;
1080  bool infra = false;
1081  std::string workDir = "./";
1082  std::string phyMode = "OfdmRate54Mbps";
1083  std::string standard ("11a");
1084  bool validate = false;
1085  uint16_t plotBianchiModel = 0x01;
1086  double maxRelativeError = 0.015;
1087  double frequency = 5;
1088  uint16_t channelWidth = 20;
1089  uint16_t guardIntervalNs = 800;
1090  uint16_t pktInterval = 1000;
1091  double distance = 0.001;
1092  double apTxPower = 16;
1093  double staTxPower = 16;
1094 
1095  // Disable fragmentation and RTS/CTS
1096  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("22000"));
1097  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("22000"));
1098  // Disable short retransmission failure (make retransmissions persistent)
1099  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (std::numeric_limits<uint32_t>::max ()));
1100  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue (std::numeric_limits<uint32_t>::max ()));
1101  // Set maximum queue size to the largest value and set maximum queue delay to be larger than the simulation time
1103  Config::SetDefault ("ns3::WifiMacQueue::MaxDelay", TimeValue (Seconds (2 * duration)));
1104 
1105  CommandLine cmd (__FILE__);
1106  cmd.AddValue ("verbose", "Logging level (0: no log - 1: simulation script logs - 2: all logs)", verbose);
1107  cmd.AddValue ("tracing", "Generate trace files", tracing);
1108  cmd.AddValue ("pktSize", "The packet size in bytes", pktSize);
1109  cmd.AddValue ("trials", "The maximal number of runs per network size", trials);
1110  cmd.AddValue ("duration", "Time duration for each trial in seconds", duration);
1111  cmd.AddValue ("pcap", "Enable/disable PCAP tracing", pcap);
1112  cmd.AddValue ("infra", "True to use infrastructure mode, false to use ring adhoc mode", infra);
1113  cmd.AddValue ("workDir", "The working directory used to store generated files", workDir);
1114  cmd.AddValue ("phyMode", "Set the constant PHY mode string used to transmit frames", phyMode);
1115  cmd.AddValue ("standard", "Set the standard (11a, 11b, 11g, 11n, 11ac, 11ax)", standard);
1116  cmd.AddValue ("nMinStas", "Minimum number of stations to start with", nMinStas);
1117  cmd.AddValue ("nMaxStas", "Maximum number of stations to start with", nMaxStas);
1118  cmd.AddValue ("nStepSize", "Number of stations to add at each step", nStepSize);
1119  cmd.AddValue ("plotBianchiModel", "First bit corresponds to the DIFS model, second bit to the EIFS model", plotBianchiModel);
1120  cmd.AddValue ("validate", "Enable/disable validation of the ns-3 simulations against the Bianchi model", validate);
1121  cmd.AddValue ("maxRelativeError", "The maximum relative error tolerated between ns-3 results and the Bianchi model (used for regression, i.e. when the validate flag is set)", maxRelativeError);
1122  cmd.AddValue ("frequency", "Set the operating frequency band in GHz: 2.4, 5 or 6", frequency);
1123  cmd.AddValue ("channelWidth", "Set the constant channel width in MHz (only for 11n/ac/ax)", channelWidth);
1124  cmd.AddValue ("guardIntervalNs", "Set the the guard interval in nanoseconds (800 or 400 for 11n/ac, 800 or 1600 or 3200 for 11 ax)", guardIntervalNs);
1125  cmd.AddValue ("maxMpdus", "Set the maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)", maxMpdus);
1126  cmd.AddValue ("distance", "Set the distance in meters between the AP and the STAs", distance);
1127  cmd.AddValue ("apTxPower", "Set the transmit power of the AP in dBm (if infrastructure only)", apTxPower);
1128  cmd.AddValue ("staTxPower", "Set the transmit power of each STA in dBm (or all STAs if adhoc)", staTxPower);
1129  cmd.AddValue ("pktInterval", "Set the socket packet interval in microseconds", pktInterval);
1130  cmd.Parse (argc, argv);
1131 
1132  if (tracing)
1133  {
1134  cwTraceFile.open ("wifi-bianchi-cw-trace.out");
1135  if (!cwTraceFile.is_open ())
1136  {
1137  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-cw-trace.out");
1138  }
1139  backoffTraceFile.open ("wifi-bianchi-backoff-trace.out");
1140  if (!backoffTraceFile.is_open ())
1141  {
1142  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-backoff-trace.out");
1143  }
1144  phyTxTraceFile.open ("wifi-bianchi-phy-tx-trace.out");
1145  if (!phyTxTraceFile.is_open ())
1146  {
1147  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-phy-tx-trace.out");
1148  }
1149  macTxTraceFile.open ("wifi-bianchi-mac-tx-trace.out");
1150  if (!macTxTraceFile.is_open ())
1151  {
1152  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-mac-tx-trace.out");
1153  }
1154  macRxTraceFile.open ("wifi-bianchi-mac-rx-trace.out");
1155  if (!macRxTraceFile.is_open ())
1156  {
1157  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-mac-rx-trace.out");
1158  }
1159  socketSendTraceFile.open ("wifi-bianchi-socket-send-trace.out");
1160  if (!socketSendTraceFile.is_open ())
1161  {
1162  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-socket-send-trace.out");
1163  }
1164  }
1165 
1166  if (verbose >= 1)
1167  {
1168  LogComponentEnable ("WifiBianchi", LOG_LEVEL_ALL);
1169  }
1170  else
1171  {
1172  LogComponentEnable ("WifiBianchi", LOG_LEVEL_WARN);
1173  }
1174  if (verbose >= 2)
1175  {
1177  }
1178 
1179  std::stringstream phyModeStr;
1180  phyModeStr << phyMode;
1181  if (phyMode.find ("Mcs") != std::string::npos)
1182  {
1183  phyModeStr << "_" << channelWidth << "MHz";
1184  }
1185 
1186  std::stringstream ss;
1187  ss << "wifi-"<< standard << "-p-" << pktSize << (infra ? "-infrastructure" : "-adhoc") << "-r-" << phyModeStr.str () << "-min-" << nMinStas << "-max-" << nMaxStas << "-step-" << nStepSize << "-throughput.plt";
1188  std::ofstream throughputPlot (ss.str ().c_str ());
1189  ss.str ("");
1190  ss << "wifi-" << standard << "-p-" << pktSize << (infra ? "-infrastructure" : "-adhoc") <<"-r-" << phyModeStr.str () << "-min-" << nMinStas << "-max-" << nMaxStas << "-step-" << nStepSize << "-throughput.eps";
1191  Gnuplot gnuplot = Gnuplot (ss.str ());
1192 
1193  WifiStandard wifiStandard;
1194  if (standard == "11a")
1195  {
1196  wifiStandard = WIFI_STANDARD_80211a;
1197  frequency = 5;
1198  channelWidth = 20;
1199  }
1200  else if (standard == "11b")
1201  {
1202  wifiStandard = WIFI_STANDARD_80211b;
1203  frequency = 2.4;
1204  channelWidth = 22;
1205  }
1206  else if (standard == "11g")
1207  {
1208  wifiStandard = WIFI_STANDARD_80211g;
1209  frequency = 2.4;
1210  channelWidth = 20;
1211  }
1212  else if (standard == "11n")
1213  {
1214  if (frequency == 2.4)
1215  {
1216  wifiStandard = WIFI_STANDARD_80211n;
1217  }
1218  else if (frequency == 5)
1219  {
1220  wifiStandard = WIFI_STANDARD_80211n;
1221  }
1222  else
1223  {
1224  NS_FATAL_ERROR ("Unsupported frequency band " << frequency << " GHz for standard " << standard);
1225  }
1226  }
1227  else if (standard == "11ac")
1228  {
1229  wifiStandard = WIFI_STANDARD_80211ac;
1230  frequency = 5;
1231  }
1232  else if (standard == "11ax")
1233  {
1234  if (frequency == 2.4)
1235  {
1236  wifiStandard = WIFI_STANDARD_80211ax;
1237  }
1238  else if (frequency == 5)
1239  {
1240  wifiStandard = WIFI_STANDARD_80211ax;
1241  }
1242  else if (frequency == 6)
1243  {
1244  wifiStandard = WIFI_STANDARD_80211ax;
1245  }
1246  else
1247  {
1248  NS_FATAL_ERROR ("Unsupported frequency band " << frequency << " GHz for standard " << standard);
1249  }
1250  }
1251  else
1252  {
1253  NS_FATAL_ERROR ("Unsupported standard: " << standard);
1254  }
1255 
1256  std::string channelStr = "{0, " + std::to_string (channelWidth) + ", BAND_"
1257  + (frequency == 2.4 ? "2_4" : (frequency == 5 ? "5" : "6"))
1258  + "GHZ, 0}";
1259  Config::SetDefault ("ns3::WifiPhy::ChannelSettings", StringValue (channelStr));
1260 
1261  YansWifiPhyHelper wifiPhy;
1262  wifiPhy.DisablePreambleDetectionModel ();
1263 
1264  YansWifiChannelHelper wifiChannel;
1265  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
1266  if (frequency == 6)
1267  {
1268  // Reference Loss for Friss at 1 m with 6.0 GHz
1269  wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel",
1270  "Exponent", DoubleValue (2.0),
1271  "ReferenceDistance", DoubleValue (1.0),
1272  "ReferenceLoss", DoubleValue (49.013));
1273  }
1274  else if (frequency == 5)
1275  {
1276  // Reference Loss for Friss at 1 m with 5.15 GHz
1277  wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel",
1278  "Exponent", DoubleValue (2.0),
1279  "ReferenceDistance", DoubleValue (1.0),
1280  "ReferenceLoss", DoubleValue (46.6777));
1281  }
1282  else
1283  {
1284  // Reference Loss for Friss at 1 m with 2.4 GHz
1285  wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel",
1286  "Exponent", DoubleValue (2.0),
1287  "ReferenceDistance", DoubleValue (1.0),
1288  "ReferenceLoss", DoubleValue (40.046));
1289  }
1290 
1291  WifiHelper wifi;
1292  wifi.SetStandard (wifiStandard);
1293  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
1294  "DataMode", StringValue (phyMode),
1295  "ControlMode", StringValue (phyMode));
1296 
1297  Gnuplot2dDataset dataset;
1298  Gnuplot2dDataset datasetBianchiEifs;
1299  Gnuplot2dDataset datasetBianchiDifs;
1302  datasetBianchiEifs.SetStyle (Gnuplot2dDataset::LINES_POINTS);
1303  datasetBianchiDifs.SetStyle (Gnuplot2dDataset::LINES_POINTS);
1304 
1306  WifiMacHelper wifiMac;
1307  double averageThroughput, throughputArray[trials];
1308  for (uint32_t n = nMinStas; n <= nMaxStas; n += nStepSize)
1309  {
1310  averageThroughput = 0;
1311  double throughput;
1312  for (uint32_t runIndex = 0; runIndex < trials; runIndex++)
1313  {
1314  packetsReceived.clear ();
1315  bytesReceived.clear ();
1316  packetsTransmitted.clear ();
1317  psduFailed.clear ();
1318  psduSucceeded.clear ();
1319  phyHeaderFailed.clear ();
1320  timeFirstReceived.clear ();
1321  timeLastReceived.clear ();
1323  rxEventWhileRxing.clear ();
1324  rxEventWhileTxing.clear ();
1325  rxEventAbortedByTx.clear ();
1326  associated.clear ();
1327  throughput = 0;
1328  std::cout << "Trial " << runIndex + 1 << " of " << trials << "; "<< phyModeStr.str () << " for " << n << " nodes " << std::endl;
1329  if (tracing)
1330  {
1331  cwTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "<< phyModeStr.str () << " for " << n << " nodes" << std::endl;
1332  backoffTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "<< phyModeStr.str () << " for " << n << " nodes" << std::endl;
1333  phyTxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1334  macTxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1335  macRxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1336  socketSendTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1337  }
1338  experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, runIndex, n, Seconds (duration), pcap, infra, guardIntervalNs, distance, apTxPower, staTxPower, MicroSeconds (pktInterval));
1339  uint32_t k = 0;
1340  if (bytesReceived.size () != n)
1341  {
1342  NS_FATAL_ERROR ("Not all stations got traffic!");
1343  }
1344  for (auto it = bytesReceived.begin (); it != bytesReceived.end (); it++, k++)
1345  {
1346  Time first = timeFirstReceived.find (it->first)->second;
1347  Time last = timeLastReceived.find (it->first)->second;
1348  Time dataTransferDuration = last - first;
1349  double nodeThroughput = (it->second * 8 / static_cast<double> (dataTransferDuration.GetMicroSeconds ()));
1350  throughput += nodeThroughput;
1351  uint64_t nodeTxPackets = GetCount (packetsTransmitted, it->first);
1352  uint64_t nodeRxPackets = GetCount (packetsReceived, it->first);
1353  uint64_t nodePhyHeaderFailures = GetCount (phyHeaderFailed, it->first);
1354  uint64_t nodePsduFailures = GetCount (psduFailed, it->first);
1355  uint64_t nodePsduSuccess = GetCount (psduSucceeded, it->first);
1356  uint64_t nodeRxEventWhileDecodingPreamble = GetCount (rxEventWhileDecodingPreamble, it->first);
1357  uint64_t nodeRxEventWhileRxing = GetCount (rxEventWhileRxing, it->first);
1358  uint64_t nodeRxEventWhileTxing = GetCount (rxEventWhileTxing, it->first);
1359  uint64_t nodeRxEventAbortedByTx = GetCount (rxEventAbortedByTx, it->first);
1360  uint64_t nodeRxEvents =
1361  nodePhyHeaderFailures + nodePsduFailures + nodePsduSuccess + nodeRxEventWhileDecodingPreamble +
1362  nodeRxEventWhileRxing + nodeRxEventWhileTxing + nodeRxEventAbortedByTx;
1363  std::cout << "Node " << it->first
1364  << ": TX packets " << nodeTxPackets
1365  << "; RX packets " << nodeRxPackets
1366  << "; PHY header failures " << nodePhyHeaderFailures
1367  << "; PSDU failures " << nodePsduFailures
1368  << "; PSDU success " << nodePsduSuccess
1369  << "; RX events while decoding preamble " << nodeRxEventWhileDecodingPreamble
1370  << "; RX events while RXing " << nodeRxEventWhileRxing
1371  << "; RX events while TXing " << nodeRxEventWhileTxing
1372  << "; RX events aborted by TX " << nodeRxEventAbortedByTx
1373  << "; total RX events " << nodeRxEvents
1374  << "; total events " << nodeTxPackets + nodeRxEvents
1375  << "; time first RX " << first
1376  << "; time last RX " << last
1377  << "; dataTransferDuration " << dataTransferDuration
1378  << "; throughput " << nodeThroughput << " Mbps" << std::endl;
1379  }
1380  std::cout << "Total throughput: " << throughput << " Mbps" << std::endl;
1381  averageThroughput += throughput;
1382  throughputArray[runIndex] = throughput;
1383  }
1384  averageThroughput = averageThroughput / trials;
1385 
1386  bool rateFound = false;
1387  double relativeErrorDifs = 0;
1388  double relativeErrorEifs = 0;
1389  auto itDifs = bianchiResultsDifs.find (phyModeStr.str ());
1390  if (itDifs != bianchiResultsDifs.end ())
1391  {
1392  rateFound = true;
1393  auto it = itDifs->second.find (n);
1394  if (it != itDifs->second.end ())
1395  {
1396  relativeErrorDifs = (std::abs (averageThroughput - it->second) / it->second);
1397  std::cout << "Relative error (DIFS): " << 100 * relativeErrorDifs << "%" << std::endl;
1398  }
1399  else if (validate)
1400  {
1401  NS_FATAL_ERROR ("No Bianchi results (DIFS) calculated for that number of stations!");
1402  }
1403  }
1404  auto itEifs = bianchiResultsEifs.find (phyModeStr.str ());
1405  if (itEifs != bianchiResultsEifs.end ())
1406  {
1407  rateFound = true;
1408  auto it = itEifs->second.find (n);
1409  if (it != itEifs->second.end ())
1410  {
1411  relativeErrorEifs = (std::abs (averageThroughput - it->second) / it->second);
1412  std::cout << "Relative error (EIFS): " << 100 * relativeErrorEifs << "%" << std::endl;
1413  }
1414  else if (validate)
1415  {
1416  NS_FATAL_ERROR ("No Bianchi results (EIFS) calculated for that number of stations!");
1417  }
1418  }
1419  if (!rateFound && validate)
1420  {
1421  NS_FATAL_ERROR ("No Bianchi results calculated for that rate!");
1422  }
1423  double relativeError = std::min (relativeErrorDifs, relativeErrorEifs);
1424  if (validate && (relativeError > maxRelativeError))
1425  {
1426  NS_FATAL_ERROR ("Relative error is too high!");
1427  }
1428 
1429  double stDev = 0;
1430  for (uint32_t i = 0; i < trials; ++i)
1431  {
1432  stDev += pow (throughputArray[i] - averageThroughput, 2);
1433  }
1434  stDev = sqrt (stDev / (trials - 1));
1435  dataset.Add (n, averageThroughput, stDev);
1436  }
1437  dataset.SetTitle ("ns-3");
1438 
1439  auto itDifs = bianchiResultsDifs.find (phyModeStr.str ());
1440  if (itDifs != bianchiResultsDifs.end ())
1441  {
1442  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1443  {
1444  double value = 0.0;
1445  auto it = itDifs->second.find (i);
1446  if (it != itDifs->second.end ())
1447  {
1448  value = it->second;
1449  }
1450  datasetBianchiDifs.Add (i, value);
1451  }
1452  }
1453  else
1454  {
1455  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1456  {
1457  datasetBianchiDifs.Add (i, 0.0);
1458  }
1459  }
1460 
1461  auto itEifs = bianchiResultsEifs.find (phyModeStr.str ());
1462  if (itEifs != bianchiResultsEifs.end ())
1463  {
1464  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1465  {
1466  double value = 0.0;
1467  auto it = itEifs->second.find (i);
1468  if (it != itEifs->second.end ())
1469  {
1470  value = it->second;
1471  }
1472  datasetBianchiEifs.Add (i, value);
1473  }
1474  }
1475  else
1476  {
1477  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1478  {
1479  datasetBianchiEifs.Add (i, 0.0);
1480  }
1481  }
1482 
1483  datasetBianchiEifs.SetTitle ("Bianchi (EIFS - lower bound)");
1484  datasetBianchiDifs.SetTitle ("Bianchi (DIFS - upper bound)");
1485  gnuplot.AddDataset (dataset);
1486  gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
1487  gnuplot.SetLegend ("Number of competing stations", "Throughput (Mbps)");
1488  ss.str ("");
1489  ss << "Frame size " << pktSize << " bytes";
1490  gnuplot.SetTitle (ss.str ());
1491  ss.str ("");
1492  ss << "set xrange [" << nMinStas << ":" << nMaxStas << "]\n"
1493  << "set xtics " << nStepSize << "\n"
1494  << "set grid xtics ytics\n"
1495  << "set mytics\n"
1496  << "set style line 1 linewidth 5\n"
1497  << "set style line 2 linewidth 5\n"
1498  << "set style line 3 linewidth 5\n"
1499  << "set style line 4 linewidth 5\n"
1500  << "set style line 5 linewidth 5\n"
1501  << "set style line 6 linewidth 5\n"
1502  << "set style line 7 linewidth 5\n"
1503  << "set style line 8 linewidth 5\n"
1504  << "set style increment user";
1505  gnuplot.SetExtra (ss.str ());
1506  if (plotBianchiModel & 0x0001)
1507  {
1508  datasetBianchiDifs.SetTitle ("Bianchi");
1509  gnuplot.AddDataset (datasetBianchiDifs);
1510  }
1511  if (plotBianchiModel & 0x0002)
1512  {
1513  datasetBianchiEifs.SetTitle ("Bianchi");
1514  gnuplot.AddDataset (datasetBianchiEifs);
1515  }
1516  if (plotBianchiModel == 0x0003)
1517  {
1518  datasetBianchiEifs.SetTitle ("Bianchi (EIFS - lower bound)");
1519  datasetBianchiDifs.SetTitle ("Bianchi (DIFS - upper bound)");
1520  }
1521  gnuplot.GenerateOutput (throughputPlot);
1522  throughputPlot.close ();
1523 
1524  if (tracing)
1525  {
1526  cwTraceFile.close ();
1527  backoffTraceFile.close ();
1528  phyTxTraceFile.close ();
1529  macTxTraceFile.close ();
1530  macRxTraceFile.close ();
1531  socketSendTraceFile.close ();
1532  }
1533 
1534  return 0;
1535 }
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
Helper class for UAN CW MAC example.
Definition: wifi-adhoc.cc:41
Gnuplot2dDataset Run(const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel)
Definition: wifi-adhoc.cc:119
a polymophic address class
Definition: address.h:91
Headers for A-MPDU subframes.
uint16_t GetLength(void) 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:229
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Class to represent a 2D points plot.
Definition: gnuplot.h:118
void SetErrorBars(enum ErrorBars errorBars)
Definition: gnuplot.cc:357
void SetStyle(enum Style style)
Definition: gnuplot.cc:346
void Add(double x, double y)
Definition: gnuplot.cc:363
void SetTitle(const std::string &title)
Change line title.
Definition: gnuplot.cc:141
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:373
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:760
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:740
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:728
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:766
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:747
void SetTitle(const std::string &title)
Definition: gnuplot.cc:734
Hold a signed integer type.
Definition: integer.h:44
an EUI-48 address
Definition: mac48-address.h:44
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(void) 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(void) const
Definition: node.cc:152
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:241
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
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:227
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
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:95
AttributeValue implementation for QueueSize.
Definition: queue-size.h:221
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:105
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:387
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
@ S
second
Definition: nstime.h:114
AttributeValue implementation for Time.
Definition: nstime.h:1308
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:274
static void EnableLogComponents(void)
Helper to enable all WifiNetDevice log components with one statement.
Definition: wifi-helper.cc:792
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
create MAC layers for a ns3::WifiNetDevice.
represent a single transmission mode
Definition: wifi-mode.h:48
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac(void) const
Address GetAddress(void) const override
void DisablePreambleDetectionModel()
Disable the preamble detection model.
Definition: wifi-helper.cc:160
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
Definition: wifi-helper.h:126
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
manage and create wifi channel objects for the YANS model.
void SetPropagationDelay(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Ptr< YansWifiChannel > Create(void) const
void AddPropagationLoss(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
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:849
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:839
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:44
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
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:44
devices
Definition: first.py:39
@ value
the parser finished reading a JSON value
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25255
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116
@ LOG_LEVEL_WARN
LOG_WARN and above.
Definition: log.h:101
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
cmd
Definition: second.py:35
ssid
Definition: third.py:100
mac
Definition: third.py:99
wifi
Definition: third.py:96
mobility
Definition: third.py:108
phy
Definition: third.py:93
def start()
Definition: core.py:1853
bool verbose
MpduInfo structure.
Definition: phy-entity.h:60
SignalNoiseDbm structure.
Definition: phy-entity.h:53
double startTime
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:79
std::map< Mac48Address, uint64_t > rxEventWhileTxing
Map that stores the number of reception events per STA that occured while PHY was already transmittin...
Definition: wifi-bianchi.cc:76
void PhyRxErrorTrace(std::string context, Ptr< const Packet > p, double snr)
std::map< Mac48Address, uint64_t > packetsReceived
Map that stores the total packets received per STA (and addressed to that STA)
Definition: wifi-bianchi.cc:70
std::ofstream backoffTraceFile
File that traces backoff over time.
Definition: wifi-bianchi.cc:64
void RestartCalc()
std::map< Mac48Address, uint64_t > bytesReceived
Map that stores the total bytes received per STA (and addressed to that STA)
Definition: wifi-bianchi.cc:71
std::map< Mac48Address, uint64_t > rxEventWhileDecodingPreamble
Map that stores the number of reception events per STA that occured while PHY was already decoding a ...
Definition: wifi-bianchi.cc:78
void AssociationLog(std::string context, Mac48Address address)
void SocketSendTrace(std::string context, Ptr< const Packet > p, const Address &addr)
bool tracing
Flag to enable/disable generation of tracing files.
Definition: wifi-bianchi.cc:88
uint32_t ContextToNodeId(std::string context)
std::map< Mac48Address, uint64_t > rxEventWhileRxing
Map that stores the number of reception events per STA that occured while PHY was already receiving a...
Definition: wifi-bianchi.cc:77
void TracePacketReception(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
void PhyRxDropTrace(std::string context, Ptr< const Packet > p, WifiPhyRxfailureReason reason)
void PhyTxTrace(std::string context, Ptr< const Packet > p, double txPowerW)
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:73
#define PI
Definition: wifi-bianchi.cc:57
std::map< Mac48Address, uint64_t > packetsTransmitted
Map that stores the total packets transmitted per STA.
Definition: wifi-bianchi.cc:72
void CwTrace(std::string context, uint32_t oldVal, uint32_t newVal)
std::map< std::string, std::map< unsigned int, double > > bianchiResultsDifs
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...
Definition: wifi-bianchi.cc:82
std::map< Mac48Address, Time > timeFirstTransmitted
Map that stores the time at which the first packet was transmitted per STA.
Definition: wifi-bianchi.cc:83
uint8_t maxMpdus
The maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)
Definition: wifi-bianchi.cc:90
void PhyRxDoneTrace(std::string context, Ptr< const Packet > p)
std::set< uint32_t > associated
Contains the IDs of the STAs that successfully associated to the access point (in infrastructure mode...
Definition: wifi-bianchi.cc:86
std::map< Mac48Address, uint64_t > phyHeaderFailed
Map that stores the total number of unsuccessfully received PHY headers per STA.
Definition: wifi-bianchi.cc:75
void MacTxTrace(std::string context, Ptr< const Packet > p)
std::ofstream socketSendTraceFile
File that traces packets transmitted by the application over time.
Definition: wifi-bianchi.cc:68
uint64_t GetCount(const std::map< Mac48Address, uint64_t > &counter, Mac48Address addr)
std::ofstream macTxTraceFile
File that traces MAC transmissions over time.
Definition: wifi-bianchi.cc:66
void PhyRxTrace(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand power)
std::ofstream phyTxTraceFile
File that traces PHY transmissions over time.
Definition: wifi-bianchi.cc:65
void IncrementCounter(std::map< Mac48Address, uint64_t > &counter, Mac48Address addr, uint64_t increment=1)
std::map< Mac48Address, Time > timeFirstReceived
Map that stores the time at which the first packet was received per STA (and the packet is addressed ...
Definition: wifi-bianchi.cc:81
void BackoffTrace(std::string context, uint32_t newVal)
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:89
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:74
std::map< Mac48Address, Time > timeLastTransmitted
Map that stores the time at which the last packet was transmitted per STA.
Definition: wifi-bianchi.cc:84
std::map< std::string, std::map< unsigned int, double > > bianchiResultsEifs
Definition: wifi-bianchi.cc:92
void MacRxTrace(std::string context, Ptr< const Packet > p)
void PhyTxDoneTrace(std::string context, Ptr< const Packet > p)
void PhyRxPayloadTrace(std::string context, WifiTxVector txVector, Time psduDuration)
Mac48Address ContextToMac(std::string context)
void PhyRxOkTrace(std::string context, Ptr< const Packet > p, double snr, WifiMode mode, WifiPreamble preamble)
void DisassociationLog(std::string context, Mac48Address address)
std::ofstream cwTraceFile
File that traces CW over time.
Definition: wifi-bianchi.cc:63
std::ofstream macRxTraceFile
File that traces MAC receptions over time.
Definition: wifi-bianchi.cc:67