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 // It currently only supports 11a/b/g, and will be later extended
25 // to support 11n/ac/ax, including frame aggregation settings.
26 
27 #include <fstream>
28 #include "ns3/log.h"
29 #include "ns3/config.h"
30 #include "ns3/gnuplot.h"
31 #include "ns3/boolean.h"
32 #include "ns3/string.h"
33 #include "ns3/double.h"
34 #include "ns3/integer.h"
35 #include "ns3/uinteger.h"
36 #include "ns3/command-line.h"
37 #include "ns3/node-list.h"
38 #include "ns3/yans-wifi-helper.h"
39 #include "ns3/ssid.h"
40 #include "ns3/wifi-mac-header.h"
41 #include "ns3/queue-size.h"
42 #include "ns3/propagation-loss-model.h"
43 #include "ns3/propagation-delay-model.h"
44 #include "ns3/rng-seed-manager.h"
45 #include "ns3/mobility-helper.h"
46 #include "ns3/wifi-net-device.h"
47 #include "ns3/packet-socket-helper.h"
48 #include "ns3/packet-socket-client.h"
49 #include "ns3/packet-socket-server.h"
50 #include "ns3/application-container.h"
51 #include "ns3/ampdu-subframe-header.h"
52 #include "ns3/wifi-mac.h"
53 
54 #define PI 3.1415926535
55 
56 NS_LOG_COMPONENT_DEFINE ("WifiBianchi");
57 
58 using namespace ns3;
59 
60 std::ofstream cwTraceFile;
61 std::ofstream backoffTraceFile;
62 std::ofstream phyTxTraceFile;
63 std::ofstream macTxTraceFile;
64 std::ofstream macRxTraceFile;
65 std::ofstream socketSendTraceFile;
66 
67 std::map<Mac48Address, uint64_t> packetsReceived;
68 std::map<Mac48Address, uint64_t> bytesReceived;
69 std::map<Mac48Address, uint64_t> packetsTransmitted;
70 std::map<Mac48Address, uint64_t> psduFailed;
71 std::map<Mac48Address, uint64_t> psduSucceeded;
72 std::map<Mac48Address, uint64_t> phyHeaderFailed;
73 std::map<Mac48Address, uint64_t> rxEventWhileTxing;
74 std::map<Mac48Address, uint64_t> rxEventWhileRxing;
75 std::map<Mac48Address, uint64_t> rxEventWhileDecodingPreamble;
76 std::map<Mac48Address, uint64_t> rxEventAbortedByTx;
77 
78 std::map<Mac48Address, Time> timeFirstReceived;
79 std::map<Mac48Address, Time> timeLastReceived;
80 std::map<Mac48Address, Time> timeFirstTransmitted;
81 std::map<Mac48Address, Time> timeLastTransmitted;
82 
83 std::set<uint32_t> associated;
84 
85 bool tracing = false;
86 uint32_t pktSize = 1500;
87 uint8_t maxMpdus = 0;
88 
89 std::map<std::string /* mode */, std::map<unsigned int /* number of nodes */, double /* calculated throughput */> > bianchiResultsEifs =
90 {
91 /* 11b */
92  {"DsssRate1Mbps", {
93  {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},
94  }},
95  {"DsssRate2Mbps", {
96  {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},
97  }},
98  {"DsssRate5_5Mbps", {
99  {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},
100  }},
101  {"DsssRate11Mbps", {
102  {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},
103  }},
104 /* 11a */
105  {"OfdmRate6Mbps", {
106  {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},
107  }},
108  {"OfdmRate9Mbps", {
109  {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},
110  }},
111  {"OfdmRate12Mbps", {
112  {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},
113  }},
114  {"OfdmRate18Mbps", {
115  {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},
116  }},
117  {"OfdmRate24Mbps", {
118  {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},
119  }},
120  {"OfdmRate36Mbps", {
121  {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},
122  }},
123  {"OfdmRate48Mbps", {
124  {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},
125  }},
126  {"OfdmRate54Mbps", {
127  {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},
128  }},
129 /* 11g */
130  {"ErpOfdmRate6Mbps", {
131  {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},
132  }},
133  {"ErpOfdmRate9Mbps", {
134  {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},
135  }},
136  {"ErpOfdmRate12Mbps", {
137  {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},
138  }},
139  {"ErpOfdmRate18Mbps", {
140  {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},
141  }},
142  {"ErpOfdmRate24Mbps", {
143  {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},
144  }},
145  {"ErpOfdmRate36Mbps", {
146  {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},
147  }},
148  {"ErpOfdmRate48Mbps", {
149  {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},
150  }},
151  {"ErpOfdmRate54Mbps", {
152  {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},
153  }},
154 /* 11ax, no frame aggregation */
155  {"HeMcs0_20MHz", {
156  {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},
157  }},
158  {"HeMcs1_20MHz", {
159  {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},
160  }},
161  {"HeMcs2_20MHz", {
162  {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},
163  }},
164  {"HeMcs3_20MHz", {
165  {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},
166  }},
167  {"HeMcs4_20MHz", {
168  {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},
169  }},
170  {"HeMcs5_20MHz", {
171  {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},
172  }},
173  {"HeMcs6_20MHz", {
174  {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},
175  }},
176  {"HeMcs7_20MHz", {
177  {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},
178  }},
179  {"HeMcs8_20MHz", {
180  {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},
181  }},
182  {"HeMcs9_20MHz", {
183  {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},
184  }},
185  {"HeMcs10_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  {"HeMcs11_20MHz", {
189  {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},
190  }},
191  {"HeMcs0_40MHz", {
192  {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},
193  }},
194  {"HeMcs1_40MHz", {
195  {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},
196  }},
197  {"HeMcs2_40MHz", {
198  {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},
199  }},
200  {"HeMcs3_40MHz", {
201  {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},
202  }},
203  {"HeMcs4_40MHz", {
204  {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},
205  }},
206  {"HeMcs5_40MHz", {
207  {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},
208  }},
209  {"HeMcs6_40MHz", {
210  {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},
211  }},
212  {"HeMcs7_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  {"HeMcs8_40MHz", {
216  {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},
217  }},
218  {"HeMcs9_40MHz", {
219  {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},
220  }},
221  {"HeMcs10_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  {"HeMcs11_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  {"HeMcs0_80MHz", {
228  {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},
229  }},
230  {"HeMcs1_80MHz", {
231  {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},
232  }},
233  {"HeMcs2_80MHz", {
234  {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},
235  }},
236  {"HeMcs3_80MHz", {
237  {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},
238  }},
239  {"HeMcs4_80MHz", {
240  {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},
241  }},
242  {"HeMcs5_80MHz", {
243  {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},
244  }},
245  {"HeMcs6_80MHz", {
246  {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},
247  }},
248  {"HeMcs7_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  {"HeMcs8_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  {"HeMcs9_80MHz", {
255  {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},
256  }},
257  {"HeMcs10_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  {"HeMcs11_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  {"HeMcs0_160MHz", {
264  {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},
265  }},
266  {"HeMcs1_160MHz", {
267  {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},
268  }},
269  {"HeMcs2_160MHz", {
270  {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},
271  }},
272  {"HeMcs3_160MHz", {
273  {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},
274  }},
275  {"HeMcs4_160MHz", {
276  {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},
277  }},
278  {"HeMcs5_160MHz", {
279  {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},
280  }},
281  {"HeMcs6_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  {"HeMcs7_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  {"HeMcs8_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  {"HeMcs9_160MHz", {
291  {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},
292  }},
293  {"HeMcs10_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  {"HeMcs11_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 };
300 
301 std::map<std::string /* mode */, std::map<unsigned int /* number of nodes */, double /* calculated throughput */> > bianchiResultsDifs =
302 {
303 /* 11b */
304  {"DsssRate1Mbps", {
305  {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},
306  }},
307  {"DsssRate2Mbps", {
308  {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},
309  }},
310  {"DsssRate5_5Mbps", {
311  {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},
312  }},
313  {"DsssRate11Mbps", {
314  {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},
315  }},
316 /* 11a */
317  {"OfdmRate6Mbps", {
318  {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},
319  }},
320  {"OfdmRate9Mbps", {
321  {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},
322  }},
323  {"OfdmRate12Mbps", {
324  {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},
325  }},
326  {"OfdmRate18Mbps", {
327  {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},
328  }},
329  {"OfdmRate24Mbps", {
330  {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},
331  }},
332  {"OfdmRate36Mbps", {
333  {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},
334  }},
335  {"OfdmRate48Mbps", {
336  {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},
337  }},
338  {"OfdmRate54Mbps", {
339  {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},
340  }},
341 /* 11g */
342  {"ErpOfdmRate6Mbps", {
343  {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},
344  }},
345  {"ErpOfdmRate9Mbps", {
346  {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},
347  }},
348  {"ErpOfdmRate12Mbps", {
349  {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},
350  }},
351  {"ErpOfdmRate18Mbps", {
352  {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},
353  }},
354  {"ErpOfdmRate24Mbps", {
355  {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},
356  }},
357  {"ErpOfdmRate36Mbps", {
358  {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},
359  }},
360  {"ErpOfdmRate48Mbps", {
361  {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},
362  }},
363  {"ErpOfdmRate54Mbps", {
364  {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},
365  }},
366 /* 11ax, no frame aggregation */
367  {"HeMcs0_20MHz", {
368  {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},
369  }},
370  {"HeMcs1_20MHz", {
371  {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},
372  }},
373  {"HeMcs2_20MHz", {
374  {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},
375  }},
376  {"HeMcs3_20MHz", {
377  {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},
378  }},
379  {"HeMcs4_20MHz", {
380  {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},
381  }},
382  {"HeMcs5_20MHz", {
383  {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},
384  }},
385  {"HeMcs6_20MHz", {
386  {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},
387  }},
388  {"HeMcs7_20MHz", {
389  {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},
390  }},
391  {"HeMcs8_20MHz", {
392  {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},
393  }},
394  {"HeMcs9_20MHz", {
395  {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},
396  }},
397  {"HeMcs10_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  {"HeMcs11_20MHz", {
401  {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},
402  }},
403  {"HeMcs0_40MHz", {
404  {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},
405  }},
406  {"HeMcs1_40MHz", {
407  {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},
408  }},
409  {"HeMcs2_40MHz", {
410  {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},
411  }},
412  {"HeMcs3_40MHz", {
413  {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},
414  }},
415  {"HeMcs4_40MHz", {
416  {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},
417  }},
418  {"HeMcs5_40MHz", {
419  {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},
420  }},
421  {"HeMcs6_40MHz", {
422  {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},
423  }},
424  {"HeMcs7_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  {"HeMcs8_40MHz", {
428  {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},
429  }},
430  {"HeMcs9_40MHz", {
431  {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},
432  }},
433  {"HeMcs10_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  {"HeMcs11_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  {"HeMcs0_80MHz", {
440  {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},
441  }},
442  {"HeMcs1_80MHz", {
443  {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},
444  }},
445  {"HeMcs2_80MHz", {
446  {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},
447  }},
448  {"HeMcs3_80MHz", {
449  {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},
450  }},
451  {"HeMcs4_80MHz", {
452  {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},
453  }},
454  {"HeMcs5_80MHz", {
455  {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},
456  }},
457  {"HeMcs6_80MHz", {
458  {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},
459  }},
460  {"HeMcs7_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  {"HeMcs8_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  {"HeMcs9_80MHz", {
467  {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},
468  }},
469  {"HeMcs10_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  {"HeMcs11_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  {"HeMcs0_160MHz", {
476  {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},
477  }},
478  {"HeMcs1_160MHz", {
479  {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},
480  }},
481  {"HeMcs2_160MHz", {
482  {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},
483  }},
484  {"HeMcs3_160MHz", {
485  {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},
486  }},
487  {"HeMcs4_160MHz", {
488  {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},
489  }},
490  {"HeMcs5_160MHz", {
491  {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},
492  }},
493  {"HeMcs6_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  {"HeMcs7_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  {"HeMcs8_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  {"HeMcs9_160MHz", {
503  {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},
504  }},
505  {"HeMcs10_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  {"HeMcs11_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 };
512 
513 // Parse context strings of the form "/NodeList/x/DeviceList/x/..." to extract the NodeId integer
514 uint32_t
515 ContextToNodeId (std::string context)
516 {
517  std::string sub = context.substr (10);
518  uint32_t pos = sub.find ("/Device");
519  return atoi (sub.substr (0, pos).c_str ());
520 }
521 
522 // Parse context strings of the form "/NodeList/x/DeviceList/x/..." and fetch the Mac address
524 ContextToMac (std::string context)
525 {
526  std::string sub = context.substr (10);
527  uint32_t pos = sub.find ("/Device");
528  uint32_t nodeId = atoi (sub.substr (0, pos).c_str ());
529  Ptr<Node> n = NodeList::GetNode (nodeId);
531  for (uint32_t i = 0; i < n->GetNDevices (); i++)
532  {
533  d = n->GetDevice (i)->GetObject<WifiNetDevice> ();
534  if (d)
535  {
536  break;
537  }
538  }
539  return Mac48Address::ConvertFrom (d->GetAddress ());
540 }
541 
542 // Functions for tracing.
543 
544 void
545 IncrementCounter (std::map<Mac48Address, uint64_t> & counter, Mac48Address addr, uint64_t increment = 1)
546 {
547  auto it = counter.find (addr);
548  if (it != counter.end ())
549  {
550  it->second += increment;
551  }
552  else
553  {
554  counter.insert (std::make_pair (addr, increment));
555  }
556 }
557 
558 void
559 TracePacketReception (std::string context, Ptr<const Packet> p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
560 {
561  Ptr<Packet> packet = p->Copy ();
562  if (txVector.IsAggregation ())
563  {
564  AmpduSubframeHeader subHdr;
565  uint32_t extractedLength;
566  packet->RemoveHeader (subHdr);
567  extractedLength = subHdr.GetLength ();
568  packet = packet->CreateFragment (0, static_cast<uint32_t> (extractedLength));
569  }
570  WifiMacHeader hdr;
571  packet->PeekHeader (hdr);
572  // hdr.GetAddr1() is the receiving MAC address
573  if (hdr.GetAddr1 () != ContextToMac (context))
574  {
575  return;
576  }
577  // hdr.GetAddr2() is the sending MAC address
578  if (packet->GetSize () >= pktSize) // ignore non-data frames
579  {
582  auto itTimeFirstReceived = timeFirstReceived.find (hdr.GetAddr2 ());
583  if (itTimeFirstReceived == timeFirstReceived.end ())
584  {
585  timeFirstReceived.insert (std::make_pair (hdr.GetAddr2 (), Simulator::Now ()));
586  }
587  auto itTimeLastReceived = timeLastReceived.find (hdr.GetAddr2 ());
588  if (itTimeLastReceived != timeLastReceived.end ())
589  {
590  itTimeLastReceived->second = Simulator::Now ();
591  }
592  else
593  {
594  timeLastReceived.insert (std::make_pair (hdr.GetAddr2 (), Simulator::Now ()));
595  }
596  }
597 }
598 
599 void
600 CwTrace (std::string context, uint32_t oldVal, uint32_t newVal)
601 {
602  NS_LOG_INFO ("CW time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " val=" << newVal);
603  if (tracing)
604  {
605  cwTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << newVal << std::endl;
606  }
607 }
608 
609 void
610 BackoffTrace (std::string context, uint32_t newVal)
611 {
612  NS_LOG_INFO ("Backoff time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " val=" << newVal);
613  if (tracing)
614  {
615  backoffTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << newVal << std::endl;
616  }
617 }
618 
619 void
621 {
622  NS_LOG_INFO ("PHY-RX-START time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize ());
623 }
624 
625 void
626 PhyRxPayloadTrace (std::string context, WifiTxVector txVector, Time psduDuration)
627 {
628  NS_LOG_INFO ("PHY-RX-PAYLOAD-START time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " psduDuration=" << psduDuration);
629 }
630 
631 void
633 {
634  NS_LOG_INFO ("PHY-RX-DROP time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize () << " reason=" << reason);
635  Mac48Address addr = ContextToMac (context);
636  switch (reason)
637  {
639  NS_FATAL_ERROR ("RX packet with unsupported settings!");
640  break;
641  case CHANNEL_SWITCHING:
642  NS_FATAL_ERROR ("Channel is switching!");
643  break;
645  {
646  if (p->GetSize () >= pktSize) // ignore non-data frames
647  {
649  }
650  break;
651  }
652  case RXING:
653  {
654  if (p->GetSize () >= pktSize) // ignore non-data frames
655  {
657  }
658  break;
659  }
660  case TXING:
661  {
662  if (p->GetSize () >= pktSize) // ignore non-data frames
663  {
665  }
666  break;
667  }
668  case SLEEPING:
669  NS_FATAL_ERROR ("Device is sleeping!");
670  break;
672  NS_FATAL_ERROR ("Preamble should always be detected!");
673  break;
675  {
676  if (p->GetSize () >= pktSize) // ignore non-data frames
677  {
679  }
680  break;
681  }
682  case L_SIG_FAILURE:
683  {
684  if (p->GetSize () >= pktSize) // ignore non-data frames
685  {
687  }
688  break;
689  }
690  case HT_SIG_FAILURE:
691  case SIG_A_FAILURE:
692  case SIG_B_FAILURE:
693  NS_FATAL_ERROR ("Unexpected PHY header failure!");
695  NS_FATAL_ERROR ("All devices should send with same power, so no packet switch during preamble detection should occur!");
696  break;
698  NS_FATAL_ERROR ("Frame capture should be disabled!");
699  break;
700  case OBSS_PD_CCA_RESET:
701  NS_FATAL_ERROR ("Unexpected CCA reset!");
702  break;
703  case UNKNOWN:
704  default:
705  NS_FATAL_ERROR ("Unknown drop reason!");
706  break;
707  }
708 }
709 
710 void
711 PhyRxDoneTrace (std::string context, Ptr<const Packet> p)
712 {
713  NS_LOG_INFO ("PHY-RX-END time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize ());
714 }
715 
716 void
717 PhyRxOkTrace (std::string context, Ptr<const Packet> p, double snr, WifiMode mode, WifiPreamble preamble)
718 {
719  uint8_t nMpdus = (p->GetSize () / pktSize);
720  NS_LOG_INFO ("PHY-RX-OK time=" << Simulator::Now ().As (Time::S)
721  << " node=" << ContextToNodeId (context)
722  << " size=" << p->GetSize ()
723  << " nMPDUs=" << +nMpdus
724  << " snr=" << snr
725  << " mode=" << mode
726  << " preamble=" << preamble);
727  if ((maxMpdus != 0) && (nMpdus != 0) && (nMpdus != maxMpdus))
728  {
729  if (nMpdus > maxMpdus)
730  {
731  NS_FATAL_ERROR ("A-MPDU settings not properly applied: maximum configured MPDUs is " << +maxMpdus << " but received an A-MPDU containing " << +nMpdus << " MPDUs");
732  }
733  NS_LOG_WARN ("Warning: less MPDUs aggregated in a received A-MPDU (" << +nMpdus << ") than configured (" << +maxMpdus << ")");
734  }
735  if (p->GetSize () >= pktSize) // ignore non-data frames
736  {
737  Mac48Address addr = ContextToMac (context);
739  }
740 }
741 
742 void
743 PhyRxErrorTrace (std::string context, Ptr<const Packet> p, double snr)
744 {
745  NS_LOG_INFO ("PHY-RX-ERROR time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize () << " snr=" << snr);
746  if (p->GetSize () >= pktSize) // ignore non-data frames
747  {
748  Mac48Address addr = ContextToMac (context);
750  }
751 }
752 
753 void
754 PhyTxTrace (std::string context, Ptr<const Packet> p, double txPowerW)
755 {
756  NS_LOG_INFO ("PHY-TX-START time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " size=" << p->GetSize () << " " << txPowerW);
757  if (tracing)
758  {
759  phyTxTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " size=" << p->GetSize () << " " << txPowerW << std::endl;
760  }
761  if (p->GetSize () >= pktSize) // ignore non-data frames
762  {
763  Mac48Address addr = ContextToMac (context);
765  }
766 }
767 
768 void
769 PhyTxDoneTrace (std::string context, Ptr<const Packet> p)
770 {
771  NS_LOG_INFO ("PHY-TX-END time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " " << p->GetSize ());
772 }
773 
774 void
775 MacTxTrace (std::string context, Ptr<const Packet> p)
776 {
777  if (tracing)
778  {
779  macTxTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << p->GetSize () << std::endl;
780  }
781 }
782 
783 void
784 MacRxTrace (std::string context, Ptr<const Packet> p)
785 {
786  if (tracing)
787  {
788  macRxTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << p->GetSize () << std::endl;
789  }
790 }
791 
792 void
793 SocketSendTrace (std::string context, Ptr<const Packet> p, const Address &addr)
794 {
795  if (tracing)
796  {
797  socketSendTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << p->GetSize () << " " << addr << std::endl;
798  }
799 }
800 
801 void
802 AssociationLog (std::string context, Mac48Address address)
803 {
804  uint32_t nodeId = ContextToNodeId (context);
805  auto it = associated.find (nodeId);
806  if (it == associated.end ())
807  {
808  NS_LOG_DEBUG ("Association: time=" << Simulator::Now () << " node=" << nodeId);
809  associated.insert (it, nodeId);
810  }
811  else
812  {
813  NS_FATAL_ERROR (nodeId << " is already associated!");
814  }
815 }
816 
817 void
818 DisassociationLog (std::string context, Mac48Address address)
819 {
820  uint32_t nodeId = ContextToNodeId (context);
821  NS_LOG_DEBUG ("Disassociation: time=" << Simulator::Now () << " node=" << nodeId);
822  NS_FATAL_ERROR ("Device should not disassociate!");
823 }
824 
825 void
827 {
828  bytesReceived.clear ();
829  packetsReceived.clear ();
830  packetsTransmitted.clear ();
831  psduFailed.clear ();
832  psduSucceeded.clear ();
833  phyHeaderFailed.clear ();
834  timeFirstReceived.clear ();
835  timeLastReceived.clear ();
837  rxEventWhileRxing.clear ();
838  rxEventWhileTxing.clear ();
839  rxEventAbortedByTx.clear ();
840 }
841 
842 class Experiment
843 {
844 public:
845  Experiment ();
846 
866  int Run (const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel,
867  uint32_t trialNumber, uint32_t networkSize, Time duration, bool pcap, bool infra, uint16_t guardIntervalNs,
868  double distanceM, double apTxPowerDbm, double staTxPowerDbm, Time pktInterval);
869 };
870 
872 {
873 }
874 
875 int
876 Experiment::Run (const WifiHelper &helper, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel,
877  uint32_t trialNumber, uint32_t networkSize, Time duration, bool pcap, bool infra, uint16_t guardIntervalNs,
878  double distance, double apTxPowerDbm, double staTxPowerDbm, Time pktInterval)
879 {
880  NodeContainer wifiNodes;
881  if (infra)
882  {
883  wifiNodes.Create (networkSize + 1);
884  }
885  else
886  {
887  wifiNodes.Create (networkSize);
888  }
889 
890  YansWifiPhyHelper phy = wifiPhy;
891  phy.SetErrorRateModel ("ns3::NistErrorRateModel");
892  phy.SetChannel (wifiChannel.Create ());
893  phy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
894 
895  WifiMacHelper mac = wifiMac;
896  WifiHelper wifi = helper;
898  uint32_t nNodes = wifiNodes.GetN ();
899  if (infra)
900  {
901  Ssid ssid = Ssid ("wifi-bianchi");
902  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)
903  mac.SetType ("ns3::ApWifiMac",
904  "BeaconInterval", TimeValue (MicroSeconds (beaconInterval)),
905  "Ssid", SsidValue (ssid));
906  phy.Set ("TxPowerStart", DoubleValue (apTxPowerDbm));
907  phy.Set ("TxPowerEnd", DoubleValue (apTxPowerDbm));
908  devices = wifi.Install (phy, mac, wifiNodes.Get (0));
909 
910  mac.SetType ("ns3::StaWifiMac",
911  "MaxMissedBeacons", UintegerValue (std::numeric_limits<uint32_t>::max ()),
912  "Ssid", SsidValue (ssid));
913  phy.Set ("TxPowerStart", DoubleValue (staTxPowerDbm));
914  phy.Set ("TxPowerEnd", DoubleValue (staTxPowerDbm));
915  for (uint32_t i = 1; i < nNodes; ++i)
916  {
917  devices.Add (wifi.Install (phy, mac, wifiNodes.Get (i)));
918  }
919  }
920  else
921  {
922  mac.SetType ("ns3::AdhocWifiMac");
923  phy.Set ("TxPowerStart", DoubleValue (staTxPowerDbm));
924  phy.Set ("TxPowerEnd", DoubleValue (staTxPowerDbm));
925  devices = wifi.Install (phy, mac, wifiNodes);
926  }
927 
928  wifi.AssignStreams (devices, trialNumber);
929 
930  Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HtConfiguration/ShortGuardIntervalSupported", BooleanValue (guardIntervalNs == 400 ? true : false));
931  Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/HeConfiguration/GuardInterval", TimeValue (NanoSeconds (guardIntervalNs)));
932 
933  // Configure aggregation
934  for (uint32_t i = 0; i < nNodes; ++i)
935  {
936  Ptr<NetDevice> dev = wifiNodes.Get (i)->GetDevice (0);
937  Ptr<WifiNetDevice> wifi_dev = DynamicCast<WifiNetDevice> (dev);
938  wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
939  wifi_dev->GetMac ()->SetAttribute ("BK_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
940  wifi_dev->GetMac ()->SetAttribute ("VO_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
941  wifi_dev->GetMac ()->SetAttribute ("VI_MaxAmpduSize", UintegerValue (maxMpdus * (pktSize + 50)));
942  }
943 
945  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
946  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
947  // Set postion for AP
948  positionAlloc->Add (Vector (1.0, 1.0, 0.0));
949 
950  // Set postion for STAs
951  double angle = (static_cast<double> (360) / (nNodes - 1));
952  for (uint32_t i = 0; i < (nNodes - 1); ++i)
953  {
954  positionAlloc->Add (Vector (1.0 + (distance * cos ((i * angle * PI) / 180)), 1.0 + (distance * sin ((i * angle * PI) / 180)), 0.0));
955  }
956 
957  mobility.SetPositionAllocator (positionAlloc);
958  mobility.Install (wifiNodes);
959 
960  PacketSocketHelper packetSocket;
961  packetSocket.Install (wifiNodes);
962 
964  Ptr<UniformRandomVariable> startTime = CreateObject<UniformRandomVariable> ();
965  startTime->SetAttribute ("Stream", IntegerValue (trialNumber));
966  startTime->SetAttribute ("Max", DoubleValue (5.0));
967 
968  uint32_t i = infra ? 1 : 0;
969  for (; i < nNodes; ++i)
970  {
971  uint32_t j = infra ? 0 : (i + 1) % nNodes;
972  PacketSocketAddress socketAddr;
973  socketAddr.SetSingleDevice (devices.Get (i)->GetIfIndex ());
974  socketAddr.SetPhysicalAddress (devices.Get (j)->GetAddress ());
975  socketAddr.SetProtocol (1);
976 
977  Ptr<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
978  client->SetRemote (socketAddr);
979  wifiNodes.Get (i)->AddApplication (client);
980  client->SetAttribute ("PacketSize", UintegerValue (pktSize));
981  client->SetAttribute ("MaxPackets", UintegerValue (0));
982  client->SetAttribute ("Interval", TimeValue (pktInterval));
983  double start = startTime->GetValue ();
984  NS_LOG_DEBUG ("Client " << i << " starting at " << start);
985  client->SetStartTime (Seconds (start));
986 
987  Ptr<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
988  server->SetLocal (socketAddr);
989  wifiNodes.Get (j)->AddApplication (server);
990  }
991 
992  // Log packet receptions
993  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx", MakeCallback (&TracePacketReception));
994 
995  // Log association and disassociation
996  if (infra)
997  {
998  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/Assoc", MakeCallback (&AssociationLog));
999  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::StaWifiMac/DeAssoc", MakeCallback (&DisassociationLog));
1000  }
1001 
1002  // Trace CW evolution
1003  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::RegularWifiMac/Txop/CwTrace", MakeCallback (&CwTrace));
1004  // Trace backoff evolution
1005  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/$ns3::RegularWifiMac/Txop/BackoffTrace", MakeCallback (&BackoffTrace));
1006  // Trace PHY Tx start events
1007  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxBegin", MakeCallback (&PhyTxTrace));
1008  // Trace PHY Tx end events
1009  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyTxEnd", MakeCallback (&PhyTxDoneTrace));
1010  // Trace PHY Rx start events
1011  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin", MakeCallback (&PhyRxTrace));
1012  // Trace PHY Rx payload start events
1013  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxPayloadBegin", MakeCallback (&PhyRxPayloadTrace));
1014  // Trace PHY Rx drop events
1015  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxDrop", MakeCallback (&PhyRxDropTrace));
1016  // Trace PHY Rx end events
1017  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxEnd", MakeCallback (&PhyRxDoneTrace));
1018  // Trace PHY Rx error events
1019  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxError", MakeCallback (&PhyRxErrorTrace));
1020  // Trace PHY Rx success events
1021  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/State/RxOk", MakeCallback (&PhyRxOkTrace));
1022  // Trace packet transmission by the device
1023  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx", MakeCallback (&MacTxTrace));
1024  // Trace packet receptions to the device
1025  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx", MakeCallback (&MacRxTrace));
1026  // Trace packets transmitted by the application
1027  Config::Connect ("/NodeList/*/$ns3::Node/ApplicationList/*/$ns3::PacketSocketClient/Tx", MakeCallback (&SocketSendTrace));
1028 
1030  Simulator::Stop (Seconds (10) + duration);
1031 
1032  if (pcap)
1033  {
1034  phy.EnablePcap ("wifi_bianchi_pcap", devices);
1035  }
1036 
1037  Simulator::Run ();
1038  Simulator::Destroy ();
1039 
1040  if (tracing)
1041  {
1042  cwTraceFile.flush ();
1043  backoffTraceFile.flush ();
1044  phyTxTraceFile.flush ();
1045  macTxTraceFile.flush ();
1046  macRxTraceFile.flush ();
1047  socketSendTraceFile.flush ();
1048  }
1049 
1050  return 0;
1051 }
1052 
1053 uint64_t
1054 GetCount (const std::map<Mac48Address, uint64_t> & counter, Mac48Address addr)
1055 {
1056  uint64_t count = 0;
1057  auto it = counter.find (addr);
1058  if (it != counter.end ())
1059  {
1060  count = it->second;
1061  }
1062  return count;
1063 }
1064 
1065 int main (int argc, char *argv[])
1066 {
1067  uint32_t nMinStas = 5;
1068  uint32_t nMaxStas = 50;
1069  uint32_t nStepSize = 5;
1070  uint32_t verbose = 0;
1071  double duration = 100;
1072  uint32_t trials = 1;
1073  bool pcap = false;
1074  bool infra = false;
1075  std::string workDir = "./";
1076  std::string phyMode = "OfdmRate54Mbps";
1077  std::string standard ("11a");
1078  bool validate = false;
1079  uint16_t plotBianchiModel = 0x01;
1080  double maxRelativeError = 0.015;
1081  double frequency = 5;
1082  uint16_t channelWidth = 20;
1083  uint16_t guardIntervalNs = 800;
1084  uint16_t pktInterval = 1000;
1085  double distance = 0.001;
1086  double apTxPower = 16;
1087  double staTxPower = 16;
1088 
1089  // Disable fragmentation and RTS/CTS
1090  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("22000"));
1091  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("22000"));
1092  // Disable short retransmission failure (make retransmissions persistent)
1093  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSlrc", UintegerValue (std::numeric_limits<uint32_t>::max ()));
1094  Config::SetDefault ("ns3::WifiRemoteStationManager::MaxSsrc", UintegerValue (std::numeric_limits<uint32_t>::max ()));
1095  // Set maximum queue size to the largest value and set maximum queue delay to be larger than the simulation time
1097  Config::SetDefault ("ns3::WifiMacQueue::MaxDelay", TimeValue (Seconds (2 * duration)));
1098 
1099  CommandLine cmd (__FILE__);
1100  cmd.AddValue ("verbose", "Logging level (0: no log - 1: simulation script logs - 2: all logs)", verbose);
1101  cmd.AddValue ("tracing", "Generate trace files", tracing);
1102  cmd.AddValue ("pktSize", "The packet size in bytes", pktSize);
1103  cmd.AddValue ("trials", "The maximal number of runs per network size", trials);
1104  cmd.AddValue ("duration", "Time duration for each trial in seconds", duration);
1105  cmd.AddValue ("pcap", "Enable/disable PCAP tracing", pcap);
1106  cmd.AddValue ("infra", "True to use infrastructure mode, false to use ring adhoc mode", infra);
1107  cmd.AddValue ("workDir", "The working directory used to store generated files", workDir);
1108  cmd.AddValue ("phyMode", "Set the constant PHY mode string used to transmit frames", phyMode);
1109  cmd.AddValue ("standard", "Set the standard (11a, 11b, 11g, 11n, 11ac, 11ax)", standard);
1110  cmd.AddValue ("nMinStas", "Minimum number of stations to start with", nMinStas);
1111  cmd.AddValue ("nMaxStas", "Maximum number of stations to start with", nMaxStas);
1112  cmd.AddValue ("nStepSize", "Number of stations to add at each step", nStepSize);
1113  cmd.AddValue ("plotBianchiModel", "First bit corresponds to the DIFS model, second bit to the EIFS model", plotBianchiModel);
1114  cmd.AddValue ("validate", "Enable/disable validation of the ns-3 simulations against the Bianchi model", validate);
1115  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);
1116  cmd.AddValue ("frequency", "Set the operating frequency band in GHz: 2.4, 5 or 6", frequency);
1117  cmd.AddValue ("channelWidth", "Set the constant channel width in MHz (only for 11n/ac/ax)", channelWidth);
1118  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);
1119  cmd.AddValue ("maxMpdus", "Set the maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)", maxMpdus);
1120  cmd.AddValue ("distance", "Set the distance in meters between the AP and the STAs", distance);
1121  cmd.AddValue ("apTxPower", "Set the transmit power of the AP in dBm (if infrastructure only)", apTxPower);
1122  cmd.AddValue ("staTxPower", "Set the transmit power of each STA in dBm (or all STAs if adhoc)", staTxPower);
1123  cmd.AddValue ("pktInterval", "Set the socket packet interval in microseconds", pktInterval);
1124  cmd.Parse (argc, argv);
1125 
1126  if (tracing)
1127  {
1128  cwTraceFile.open ("wifi-bianchi-cw-trace.out");
1129  if (!cwTraceFile.is_open ())
1130  {
1131  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-cw-trace.out");
1132  }
1133  backoffTraceFile.open ("wifi-bianchi-backoff-trace.out");
1134  if (!backoffTraceFile.is_open ())
1135  {
1136  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-backoff-trace.out");
1137  }
1138  phyTxTraceFile.open ("wifi-bianchi-phy-tx-trace.out");
1139  if (!phyTxTraceFile.is_open ())
1140  {
1141  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-phy-tx-trace.out");
1142  }
1143  macTxTraceFile.open ("wifi-bianchi-mac-tx-trace.out");
1144  if (!macTxTraceFile.is_open ())
1145  {
1146  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-mac-tx-trace.out");
1147  }
1148  macRxTraceFile.open ("wifi-bianchi-mac-rx-trace.out");
1149  if (!macRxTraceFile.is_open ())
1150  {
1151  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-mac-rx-trace.out");
1152  }
1153  socketSendTraceFile.open ("wifi-bianchi-socket-send-trace.out");
1154  if (!socketSendTraceFile.is_open ())
1155  {
1156  NS_FATAL_ERROR ("Failed to open file wifi-bianchi-socket-send-trace.out");
1157  }
1158  }
1159 
1160  if (verbose >= 1)
1161  {
1162  LogComponentEnable ("WifiBianchi", LOG_LEVEL_ALL);
1163  }
1164  else
1165  {
1166  LogComponentEnable ("WifiBianchi", LOG_LEVEL_WARN);
1167  }
1168  if (verbose >= 2)
1169  {
1171  }
1172 
1173  Config::SetDefault ("ns3::WifiPhy::ChannelWidth", UintegerValue (channelWidth));
1174  std::stringstream phyModeStr;
1175  phyModeStr << phyMode;
1176  if (phyMode.find ("Mcs") != std::string::npos)
1177  {
1178  phyModeStr << "_" << channelWidth << "MHz";
1179  }
1180 
1181  std::stringstream ss;
1182  ss << "wifi-"<< standard << "-p-" << pktSize << (infra ? "-infrastructure" : "-adhoc") << "-r-" << phyModeStr.str () << "-min-" << nMinStas << "-max-" << nMaxStas << "-step-" << nStepSize << "-throughput.plt";
1183  std::ofstream throughputPlot (ss.str ().c_str ());
1184  ss.str ("");
1185  ss << "wifi-" << standard << "-p-" << pktSize << (infra ? "-infrastructure" : "-adhoc") <<"-r-" << phyModeStr.str () << "-min-" << nMinStas << "-max-" << nMaxStas << "-step-" << nStepSize << "-throughput.eps";
1186  Gnuplot gnuplot = Gnuplot (ss.str ());
1187 
1188  WifiStandard wifiStandard;
1189  if (standard == "11a")
1190  {
1191  wifiStandard = WIFI_STANDARD_80211a;
1192  frequency = 5;
1193  channelWidth = 20;
1194  }
1195  else if (standard == "11b")
1196  {
1197  wifiStandard = WIFI_STANDARD_80211b;
1198  frequency = 2.4;
1199  channelWidth = 22;
1200  }
1201  else if (standard == "11g")
1202  {
1203  wifiStandard = WIFI_STANDARD_80211g;
1204  frequency = 2.4;
1205  channelWidth = 20;
1206  }
1207  else if (standard == "11n")
1208  {
1209  if (frequency == 2.4)
1210  {
1211  wifiStandard = WIFI_STANDARD_80211n_2_4GHZ;
1212  }
1213  else if (frequency == 5)
1214  {
1215  wifiStandard = WIFI_STANDARD_80211n_5GHZ;
1216  }
1217  else
1218  {
1219  NS_FATAL_ERROR ("Unsupported frequency band " << frequency << " GHz for standard " << standard);
1220  }
1221  }
1222  else if (standard == "11ac")
1223  {
1224  wifiStandard = WIFI_STANDARD_80211ac;
1225  frequency = 5;
1226  }
1227  else if (standard == "11ax")
1228  {
1229  if (frequency == 2.4)
1230  {
1231  wifiStandard = WIFI_STANDARD_80211ax_2_4GHZ;
1232  }
1233  else if (frequency == 5)
1234  {
1235  wifiStandard = WIFI_STANDARD_80211ax_5GHZ;
1236  }
1237  else if (frequency == 6)
1238  {
1239  wifiStandard = WIFI_STANDARD_80211ax_6GHZ;
1240  }
1241  else
1242  {
1243  NS_FATAL_ERROR ("Unsupported frequency band " << frequency << " GHz for standard " << standard);
1244  }
1245  }
1246  else
1247  {
1248  NS_FATAL_ERROR ("Unsupported standard: " << standard);
1249  }
1250 
1251  YansWifiPhyHelper wifiPhy;
1252  wifiPhy.DisablePreambleDetectionModel ();
1253 
1254  YansWifiChannelHelper wifiChannel;
1255  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
1256  if (frequency == 6)
1257  {
1258  // Reference Loss for Friss at 1 m with 6.0 GHz
1259  wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel",
1260  "Exponent", DoubleValue (2.0),
1261  "ReferenceDistance", DoubleValue (1.0),
1262  "ReferenceLoss", DoubleValue (49.013));
1263  }
1264  else if (frequency == 5)
1265  {
1266  // Reference Loss for Friss at 1 m with 5.15 GHz
1267  wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel",
1268  "Exponent", DoubleValue (2.0),
1269  "ReferenceDistance", DoubleValue (1.0),
1270  "ReferenceLoss", DoubleValue (46.6777));
1271  }
1272  else
1273  {
1274  // Reference Loss for Friss at 1 m with 2.4 GHz
1275  wifiChannel.AddPropagationLoss ("ns3::LogDistancePropagationLossModel",
1276  "Exponent", DoubleValue (2.0),
1277  "ReferenceDistance", DoubleValue (1.0),
1278  "ReferenceLoss", DoubleValue (40.046));
1279  }
1280 
1281  WifiHelper wifi;
1282  wifi.SetStandard (wifiStandard);
1283  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
1284  "DataMode", StringValue (phyMode),
1285  "ControlMode", StringValue (phyMode));
1286 
1287  Gnuplot2dDataset dataset;
1288  Gnuplot2dDataset datasetBianchiEifs;
1289  Gnuplot2dDataset datasetBianchiDifs;
1292  datasetBianchiEifs.SetStyle (Gnuplot2dDataset::LINES_POINTS);
1293  datasetBianchiDifs.SetStyle (Gnuplot2dDataset::LINES_POINTS);
1294 
1296  WifiMacHelper wifiMac;
1297  double averageThroughput, throughputArray[trials];
1298  for (uint32_t n = nMinStas; n <= nMaxStas; n += nStepSize)
1299  {
1300  averageThroughput = 0;
1301  double throughput;
1302  for (uint32_t runIndex = 0; runIndex < trials; runIndex++)
1303  {
1304  packetsReceived.clear ();
1305  bytesReceived.clear ();
1306  packetsTransmitted.clear ();
1307  psduFailed.clear ();
1308  psduSucceeded.clear ();
1309  phyHeaderFailed.clear ();
1310  timeFirstReceived.clear ();
1311  timeLastReceived.clear ();
1313  rxEventWhileRxing.clear ();
1314  rxEventWhileTxing.clear ();
1315  rxEventAbortedByTx.clear ();
1316  associated.clear ();
1317  throughput = 0;
1318  std::cout << "Trial " << runIndex + 1 << " of " << trials << "; "<< phyModeStr.str () << " for " << n << " nodes " << std::endl;
1319  if (tracing)
1320  {
1321  cwTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "<< phyModeStr.str () << " for " << n << " nodes" << std::endl;
1322  backoffTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; "<< phyModeStr.str () << " for " << n << " nodes" << std::endl;
1323  phyTxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1324  macTxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1325  macRxTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1326  socketSendTraceFile << "# Trial " << runIndex + 1 << " of " << trials << "; " << phyModeStr.str () << " for " << n << " nodes" << std::endl;
1327  }
1328  experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, runIndex, n, Seconds (duration), pcap, infra, guardIntervalNs, distance, apTxPower, staTxPower, MicroSeconds (pktInterval));
1329  uint32_t k = 0;
1330  if (bytesReceived.size () != n)
1331  {
1332  NS_FATAL_ERROR ("Not all stations got traffic!");
1333  }
1334  for (auto it = bytesReceived.begin (); it != bytesReceived.end (); it++, k++)
1335  {
1336  Time first = timeFirstReceived.find (it->first)->second;
1337  Time last = timeLastReceived.find (it->first)->second;
1338  Time dataTransferDuration = last - first;
1339  double nodeThroughput = (it->second * 8 / static_cast<double> (dataTransferDuration.GetMicroSeconds ()));
1340  throughput += nodeThroughput;
1341  uint64_t nodeTxPackets = GetCount (packetsTransmitted, it->first);
1342  uint64_t nodeRxPackets = GetCount (packetsReceived, it->first);
1343  uint64_t nodePhyHeaderFailures = GetCount (phyHeaderFailed, it->first);
1344  uint64_t nodePsduFailures = GetCount (psduFailed, it->first);
1345  uint64_t nodePsduSuccess = GetCount (psduSucceeded, it->first);
1346  uint64_t nodeRxEventWhileDecodingPreamble = GetCount (rxEventWhileDecodingPreamble, it->first);
1347  uint64_t nodeRxEventWhileRxing = GetCount (rxEventWhileRxing, it->first);
1348  uint64_t nodeRxEventWhileTxing = GetCount (rxEventWhileTxing, it->first);
1349  uint64_t nodeRxEventAbortedByTx = GetCount (rxEventAbortedByTx, it->first);
1350  uint64_t nodeRxEvents =
1351  nodePhyHeaderFailures + nodePsduFailures + nodePsduSuccess + nodeRxEventWhileDecodingPreamble +
1352  nodeRxEventWhileRxing + nodeRxEventWhileTxing + nodeRxEventAbortedByTx;
1353  std::cout << "Node " << it->first
1354  << ": TX packets " << nodeTxPackets
1355  << "; RX packets " << nodeRxPackets
1356  << "; PHY header failures " << nodePhyHeaderFailures
1357  << "; PSDU failures " << nodePsduFailures
1358  << "; PSDU success " << nodePsduSuccess
1359  << "; RX events while decoding preamble " << nodeRxEventWhileDecodingPreamble
1360  << "; RX events while RXing " << nodeRxEventWhileRxing
1361  << "; RX events while TXing " << nodeRxEventWhileTxing
1362  << "; RX events aborted by TX " << nodeRxEventAbortedByTx
1363  << "; total RX events " << nodeRxEvents
1364  << "; total events " << nodeTxPackets + nodeRxEvents
1365  << "; time first RX " << first
1366  << "; time last RX " << last
1367  << "; dataTransferDuration " << dataTransferDuration
1368  << "; throughput " << nodeThroughput << " Mbps" << std::endl;
1369  }
1370  std::cout << "Total throughput: " << throughput << " Mbps" << std::endl;
1371  averageThroughput += throughput;
1372  throughputArray[runIndex] = throughput;
1373  }
1374  averageThroughput = averageThroughput / trials;
1375 
1376  bool rateFound = false;
1377  double relativeErrorDifs = 0;
1378  double relativeErrorEifs = 0;
1379  auto itDifs = bianchiResultsDifs.find (phyModeStr.str ());
1380  if (itDifs != bianchiResultsDifs.end ())
1381  {
1382  rateFound = true;
1383  auto it = itDifs->second.find (n);
1384  if (it != itDifs->second.end ())
1385  {
1386  relativeErrorDifs = (std::abs (averageThroughput - it->second) / it->second);
1387  std::cout << "Relative error (DIFS): " << 100 * relativeErrorDifs << "%" << std::endl;
1388  }
1389  else if (validate)
1390  {
1391  NS_FATAL_ERROR ("No Bianchi results (DIFS) calculated for that number of stations!");
1392  }
1393  }
1394  auto itEifs = bianchiResultsEifs.find (phyModeStr.str ());
1395  if (itEifs != bianchiResultsEifs.end ())
1396  {
1397  rateFound = true;
1398  auto it = itEifs->second.find (n);
1399  if (it != itEifs->second.end ())
1400  {
1401  relativeErrorEifs = (std::abs (averageThroughput - it->second) / it->second);
1402  std::cout << "Relative error (EIFS): " << 100 * relativeErrorEifs << "%" << std::endl;
1403  }
1404  else if (validate)
1405  {
1406  NS_FATAL_ERROR ("No Bianchi results (EIFS) calculated for that number of stations!");
1407  }
1408  }
1409  if (!rateFound && validate)
1410  {
1411  NS_FATAL_ERROR ("No Bianchi results calculated for that rate!");
1412  }
1413  double relativeError = std::min (relativeErrorDifs, relativeErrorEifs);
1414  if (validate && (relativeError > maxRelativeError))
1415  {
1416  NS_FATAL_ERROR ("Relative error is too high!");
1417  }
1418 
1419  double stDev = 0;
1420  for (uint32_t i = 0; i < trials; ++i)
1421  {
1422  stDev += pow (throughputArray[i] - averageThroughput, 2);
1423  }
1424  stDev = sqrt (stDev / (trials - 1));
1425  dataset.Add (n, averageThroughput, stDev);
1426  }
1427  dataset.SetTitle ("ns-3");
1428 
1429  auto itDifs = bianchiResultsDifs.find (phyModeStr.str ());
1430  if (itDifs != bianchiResultsDifs.end ())
1431  {
1432  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1433  {
1434  double value = 0.0;
1435  auto it = itDifs->second.find (i);
1436  if (it != itDifs->second.end ())
1437  {
1438  value = it->second;
1439  }
1440  datasetBianchiDifs.Add (i, value);
1441  }
1442  }
1443  else
1444  {
1445  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1446  {
1447  datasetBianchiDifs.Add (i, 0.0);
1448  }
1449  }
1450 
1451  auto itEifs = bianchiResultsEifs.find (phyModeStr.str ());
1452  if (itEifs != bianchiResultsEifs.end ())
1453  {
1454  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1455  {
1456  double value = 0.0;
1457  auto it = itEifs->second.find (i);
1458  if (it != itEifs->second.end ())
1459  {
1460  value = it->second;
1461  }
1462  datasetBianchiEifs.Add (i, value);
1463  }
1464  }
1465  else
1466  {
1467  for (uint32_t i = nMinStas; i <= nMaxStas; i += nStepSize)
1468  {
1469  datasetBianchiEifs.Add (i, 0.0);
1470  }
1471  }
1472 
1473  datasetBianchiEifs.SetTitle ("Bianchi (EIFS - lower bound)");
1474  datasetBianchiDifs.SetTitle ("Bianchi (DIFS - upper bound)");
1475  gnuplot.AddDataset (dataset);
1476  gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
1477  gnuplot.SetLegend ("Number of competing stations", "Throughput (Mbps)");
1478  ss.str ("");
1479  ss << "Frame size " << pktSize << " bytes";
1480  gnuplot.SetTitle (ss.str ());
1481  ss.str ("");
1482  ss << "set xrange [" << nMinStas << ":" << nMaxStas << "]\n"
1483  << "set xtics " << nStepSize << "\n"
1484  << "set grid xtics ytics\n"
1485  << "set mytics\n"
1486  << "set style line 1 linewidth 5\n"
1487  << "set style line 2 linewidth 5\n"
1488  << "set style line 3 linewidth 5\n"
1489  << "set style line 4 linewidth 5\n"
1490  << "set style line 5 linewidth 5\n"
1491  << "set style line 6 linewidth 5\n"
1492  << "set style line 7 linewidth 5\n"
1493  << "set style line 8 linewidth 5\n"
1494  << "set style increment user";
1495  gnuplot.SetExtra (ss.str ());
1496  if (plotBianchiModel & 0x0001)
1497  {
1498  datasetBianchiDifs.SetTitle ("Bianchi");
1499  gnuplot.AddDataset (datasetBianchiDifs);
1500  }
1501  if (plotBianchiModel & 0x0002)
1502  {
1503  datasetBianchiEifs.SetTitle ("Bianchi");
1504  gnuplot.AddDataset (datasetBianchiEifs);
1505  }
1506  if (plotBianchiModel == 0x0003)
1507  {
1508  datasetBianchiEifs.SetTitle ("Bianchi (EIFS - lower bound)");
1509  datasetBianchiDifs.SetTitle ("Bianchi (DIFS - upper bound)");
1510  }
1511  gnuplot.GenerateOutput (throughputPlot);
1512  throughputPlot.close ();
1513 
1514  if (tracing)
1515  {
1516  cwTraceFile.close ();
1517  backoffTraceFile.close ();
1518  phyTxTraceFile.close ();
1519  macTxTraceFile.close ();
1520  macRxTraceFile.close ();
1521  socketSendTraceFile.close ();
1522  }
1523 
1524  return 0;
1525 }
MpduInfo structure.
Definition: phy-entity.h:59
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())
Helper class for UAN CW MAC example.
Definition: wifi-adhoc.cc:40
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
holds a vector of ns3::Application pointers.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:159
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
void MacTxTrace(std::string context, Ptr< const Packet > p)
AttributeValue implementation for Boolean.
Definition: boolean.h:36
Class for representing queue sizes.
Definition: queue-size.h:94
void SetLocal(PacketSocketAddress addr)
set the local address and protocol to be used
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void IncrementCounter(std::map< Mac48Address, uint64_t > &counter, Mac48Address addr, uint64_t increment=1)
Class to represent a 2D points plot.
Definition: gnuplot.h:117
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:78
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
uint8_t maxMpdus
The maximum number of MPDUs in A-MPDUs (0 to disable MPDU aggregation)
Definition: wifi-bianchi.cc:87
void SetTitle(const std::string &title)
Change line title.
Definition: gnuplot.cc:141
Hold variables of type string.
Definition: string.h:41
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:241
Make it easy to create and manage PHY objects for the YANS model.
#define min(a, b)
Definition: 80211b.c:42
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:839
std::map< Mac48Address, uint64_t > bytesReceived
Map that stores the total bytes received per STA (and addressed to that STA)
Definition: wifi-bianchi.cc:68
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
void DisassociationLog(std::string context, Mac48Address address)
std::ofstream macTxTraceFile
File that traces MAC transmissions over time.
Definition: wifi-bianchi.cc:63
def start()
Definition: core.py:1855
void TracePacketReception(std::string context, Ptr< const Packet > p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId)
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
an address for a packet socket
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
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
Hold a signed integer type.
Definition: integer.h:44
void PhyRxOkTrace(std::string context, Ptr< const Packet > p, double snr, WifiMode mode, WifiPreamble preamble)
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
std::map< Mac48Address, Time > timeLastTransmitted
Map that stores the time at which the last packet was transmitted per STA.
Definition: wifi-bianchi.cc:81
std::map< std::string, std::map< unsigned int, double > > bianchiResultsDifs
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:756
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
Mac48Address ContextToMac(std::string context)
cmd
Definition: second.py:35
void AssociationLog(std::string context, Mac48Address address)
void PhyTxDoneTrace(std::string context, Ptr< const Packet > p)
void BackoffTrace(std::string context, uint32_t newVal)
helps to create WifiNetDevice objects
Definition: wifi-helper.h:326
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:47
uint32_t ContextToNodeId(std::string context)
Give ns3::PacketSocket powers to ns3::Node.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
a polymophic address class
Definition: address.h:90
Ptr< YansWifiChannel > Create(void) const
std::map< Mac48Address, uint64_t > phyHeaderFailed
Map that stores the total number of unsuccessfully received PHY headers per STA.
Definition: wifi-bianchi.cc:72
mobility
Definition: third.py:108
void SetErrorBars(enum ErrorBars errorBars)
Definition: gnuplot.cc:353
phy
Definition: third.py:93
#define PI
Definition: wifi-bianchi.cc:54
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
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:73
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:70
void PhyRxDropTrace(std::string context, Ptr< const Packet > p, WifiPhyRxfailureReason reason)
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:76
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
uint64_t GetCount(const std::map< Mac48Address, uint64_t > &counter, Mac48Address addr)
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:371
#define max(a, b)
Definition: 80211b.c:43
std::ofstream socketSendTraceFile
File that traces packets transmitted by the application over time.
Definition: wifi-bianchi.cc:65
AttributeValue implementation for Time.
Definition: nstime.h:1353
void SetTitle(const std::string &title)
Definition: gnuplot.cc:730
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
void MacRxTrace(std::string context, Ptr< const Packet > p)
Hold an unsigned integer type.
Definition: uinteger.h:44
Address GetAddress(void) const override
double startTime
ssid
Definition: third.py:100
Use number of packets for queue size.
Definition: queue-size.h:44
holds a vector of ns3::NetDevice pointers
mac
Definition: third.py:99
void RestartCalc()
Headers for A-MPDU subframes.
std::map< Mac48Address, uint64_t > packetsReceived
Map that stores the total packets received per STA (and addressed to that STA)
Definition: wifi-bianchi.cc:67
void PhyTxTrace(std::string context, Ptr< const Packet > p, double txPowerW)
Hold together all Wifi-related objects.
LOG_WARN and above.
Definition: log.h:101
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:762
std::map< Mac48Address, uint64_t > packetsTransmitted
Map that stores the total packets transmitted per STA.
Definition: wifi-bianchi.cc:69
void Add(double x, double y)
Definition: gnuplot.cc:359
void SocketSendTrace(std::string context, Ptr< const Packet > p, const Address &addr)
Parse command-line arguments.
Definition: command-line.h:227
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:736
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static Mac48Address ConvertFrom(const Address &address)
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
uint32_t GetN(void) const
Get the number of Ptr<Node> stored in this container.
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:388
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:71
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
WifiStandard
Identifies the allowed configurations that a Wifi device is configured to use.
keep track of a set of node pointers.
address
Definition: first.py:44
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
void CwTrace(std::string context, uint32_t oldVal, uint32_t newVal)
an EUI-48 address
Definition: mac48-address.h:43
manage and create wifi channel objects for the YANS model.
std::ofstream macRxTraceFile
File that traces MAC receptions over time.
Definition: wifi-bianchi.cc:64
void PhyRxDoneTrace(std::string context, Ptr< const Packet > p)
create MAC layers for a ns3::WifiNetDevice.
void SetStyle(enum Style style)
Definition: gnuplot.cc:342
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void PhyRxTrace(std::string context, Ptr< const Packet > p, RxPowerWattPerChannelBand power)
void PhyRxPayloadTrace(std::string context, WifiTxVector txVector, Time psduDuration)
std::ofstream backoffTraceFile
File that traces backoff over time.
Definition: wifi-bianchi.cc:61
void SetExtra(const std::string &extra)
Definition: gnuplot.cc:743
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:35
std::ofstream cwTraceFile
File that traces CW over time.
Definition: wifi-bianchi.cc:60
Gnuplot2dDataset Run(const WifiHelper &wifi, const YansWifiPhyHelper &wifiPhy, const WifiMacHelper &wifiMac, const YansWifiChannelHelper &wifiChannel)
Definition: wifi-adhoc.cc:119
void PhyRxErrorTrace(std::string context, Ptr< const Packet > p, double snr)
wifi
Definition: third.py:96
Helper class used to assign positions and mobility models to nodes.
std::map< std::string, std::map< unsigned int, double > > bianchiResultsEifs
Definition: wifi-bianchi.cc:89
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:83
static void EnableLogComponents(void)
Helper to enable all WifiNetDevice log components with one statement.
Definition: wifi-helper.cc:914
Ptr< WifiMac > GetMac(void) const
void experiment(std::string queue_disc_type)
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:74
void SetRemote(PacketSocketAddress addr)
set the remote address and protocol to be used
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
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:79
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
SignalNoiseDbm structure.
Definition: phy-entity.h:52
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
AttributeValue implementation for Ssid.
Definition: ssid.h:105
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
void SetProtocol(uint16_t protocol)
Set the protocol.
void Add(Vector v)
Add a position to the list of positions.
uint16_t GetLength(void) const
Return the length field.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
std::ofstream phyTxTraceFile
File that traces PHY transmissions over time.
Definition: wifi-bianchi.cc:62
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Print everything.
Definition: log.h:116
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
second
Definition: nstime.h:115
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:75
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())
devices
Definition: first.py:39
void DisablePreambleDetectionModel()
Disable the preamble detection model.
Definition: wifi-helper.cc:215
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:724
Definition: first.py:1
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:86
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
Include Radiotap link layer information.
Definition: wifi-helper.h:180
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
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:1642
bool tracing
Flag to enable/disable generation of tracing files.
Definition: wifi-bianchi.cc:85
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
Implements the IEEE 802.11 MAC header.
bool verbose
std::map< Mac48Address, Time > timeFirstTransmitted
Map that stores the time at which the first packet was transmitted per STA.
Definition: wifi-bianchi.cc:80