A Discrete-Event Network Simulator
API
wifi-error-rate-models-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 University of Washington
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  * Authors: Tom Henderson (tomhend@u.washington.edu)
19  * Sébastien Deronne (sebastien.deronne@gmail.com)
20  */
21 
22 #include "ns3/log.h"
23 #include "ns3/test.h"
24 #include "ns3/nist-error-rate-model.h"
25 #include "ns3/yans-error-rate-model.h"
26 #include "ns3/dsss-error-rate-model.h"
27 #include "ns3/wifi-phy.h"
28 #include "ns3/wifi-utils.h"
29 #include "ns3/table-based-error-rate-model.h"
30 
31 using namespace ns3;
32 
33 NS_LOG_COMPONENT_DEFINE ("WifiErrorRateModelsTest");
34 
35 static double
36 FromRss (double rssDbw)
37 {
38  // SINR is based on receiver noise figure of 7 dB and thermal noise
39  // of -100.5522786 dBm in this 22 MHz bandwidth at 290K
40  double noisePowerDbw = -100.5522786 + 7;
41 
42  double sinrDb = rssDbw - noisePowerDbw;
43  // return SINR expressed as ratio
44  return pow (10.0, sinrDb / 10.0);
45 }
46 
54 {
55 public:
58 
59 private:
60  virtual void DoRun (void);
61 };
62 
64  : TestCase ("WifiErrorRateModel test case DSSS")
65 {
66 }
67 
69 {
70 }
71 
72 void
74 {
75  // 1024 bytes plus headers
76  uint64_t size = (1024 + 40 + 14) * 8;
77  // Spot test some values returned from DsssErrorRateModel
78  // Values taken from sample 80211b.c program used in validation paper
79  double value;
80  // DBPSK
81  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-105.0), size);
82  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0, 1e-13, "Not equal within tolerance");
83  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-100.0), size);
84  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1.5e-13, 1e-13, "Not equal within tolerance");
85  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-99.0), size);
86  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.0003, 0.0001, "Not equal within tolerance");
87  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-98.0), size);
88  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.202, 0.005, "Not equal within tolerance");
89  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-97.0), size);
90  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.813, 0.005, "Not equal within tolerance");
91  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-96.0), size);
92  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.984, 0.005, "Not equal within tolerance");
93  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-95.0), size);
94  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.999, 0.001, "Not equal within tolerance");
95  value = DsssErrorRateModel::GetDsssDbpskSuccessRate (FromRss (-90.0), size);
96  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1, 0.001, "Not equal within tolerance");
97 
98  // DQPSK
99  //
100  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-96.0), size);
101  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0, 1e-13, "Not equal within tolerance");
102  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-95.0), size);
103  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4.5e-6, 1e-6, "Not equal within tolerance");
104  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-94.0), size);
105  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.036, 0.005, "Not equal within tolerance");
106  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-93.0), size);
107  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.519, 0.005, "Not equal within tolerance");
108  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-92.0), size);
109  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.915, 0.005, "Not equal within tolerance");
110  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-91.0), size);
111  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.993, 0.005, "Not equal within tolerance");
112  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-90.0), size);
113  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.999, 0.001, "Not equal within tolerance");
114  value = DsssErrorRateModel::GetDsssDqpskSuccessRate (FromRss (-89.0), size);
115  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1, 0.001, "Not equal within tolerance");
116 
117 #ifdef HAVE_GSL
118  // DQPSK_CCK5.5
119  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-94.0), size);
120  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0, 1e-13, "Not equal within tolerance");
121  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-93.0), size);
122  NS_TEST_ASSERT_MSG_EQ_TOL (value, 6.6e-14, 5e-14, "Not equal within tolerance");
123  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-92.0), size);
124  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.0001, 0.00005, "Not equal within tolerance");
125  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-91.0), size);
126  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.132, 0.005, "Not equal within tolerance");
127  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-90.0), size);
128  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.744, 0.005, "Not equal within tolerance");
129  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-89.0), size);
130  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.974, 0.005, "Not equal within tolerance");
131  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-88.0), size);
132  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.999, 0.001, "Not equal within tolerance");
133  value = DsssErrorRateModel::GetDsssDqpskCck5_5SuccessRate (FromRss (-87.0), size);
134  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1, 0.001, "Not equal within tolerance");
135 
136  // DQPSK_CCK11
137  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-91.0), size);
138  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0, 1e-14, "Not equal within tolerance");
139  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-90.0), size);
140  NS_TEST_ASSERT_MSG_EQ_TOL (value, 4.7e-14, 1e-14, "Not equal within tolerance");
141  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-89.0), size);
142  NS_TEST_ASSERT_MSG_EQ_TOL (value, 8.85e-5, 1e-5, "Not equal within tolerance");
143  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-88.0), size);
144  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.128, 0.005, "Not equal within tolerance");
145  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-87.0), size);
146  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.739, 0.005, "Not equal within tolerance");
147  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-86.0), size);
148  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.973, 0.005, "Not equal within tolerance");
149  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-85.0), size);
150  NS_TEST_ASSERT_MSG_EQ_TOL (value, 0.999, 0.001, "Not equal within tolerance");
151  value = DsssErrorRateModel::GetDsssDqpskCck11SuccessRate (FromRss (-84.0), size);
152  NS_TEST_ASSERT_MSG_EQ_TOL (value, 1, 0.001, "Not equal within tolerance");
153 #endif
154 }
155 
163 {
164 public:
167 
168 private:
169  virtual void DoRun (void);
170 };
171 
173  : TestCase ("WifiErrorRateModel test case NIST")
174 {
175 }
176 
178 {
179 }
180 
181 void
183 {
184  uint32_t frameSize = 2000;
185  WifiTxVector txVector;
186  Ptr<NistErrorRateModel> nist = CreateObject<NistErrorRateModel> ();
187 
188  double ps; // probability of success
189  double snr; // dB
190 
191  // Spot test some values returned from NistErrorRateModel
192  // values can be generated by the example program ofdm-validation.cc
193  snr = 2.5;
194  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate6Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
195  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 2.04e-10, 1e-10, "Not equal within tolerance");
196  snr = 3.0;
197  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate6Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
198  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.020, 0.001, "Not equal within tolerance");
199  snr = 4.0;
200  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate6Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
201  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.885, 0.001, "Not equal within tolerance");
202  snr = 5.0;
203  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate6Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
204  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.997, 0.001, "Not equal within tolerance");
205 
206  snr = 6.0;
207  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate9Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
208  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.097, 0.001, "Not equal within tolerance");
209  snr = 7.0;
210  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate9Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
211  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.918, 0.001, "Not equal within tolerance");
212  snr = 8.0;
213  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate9Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
214  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.998, 0.001, "Not equal within tolerance");
215  snr = 9.0;
216  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate9Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
217  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.999, 0.001, "Not equal within tolerance");
218 
219  snr = 6.0;
220  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate12Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
221  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.0174, 0.001, "Not equal within tolerance");
222  snr = 7.0;
223  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate12Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
224  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.881, 0.001, "Not equal within tolerance");
225  snr = 8.0;
226  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate12Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
227  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.997, 0.001, "Not equal within tolerance");
228  snr = 9.0;
229  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate12Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
230  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.999, 0.001, "Not equal within tolerance");
231 
232  snr = 8.5;
233  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate18Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
234  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 2.85e-6, 1e-6, "Not equal within tolerance");
235  snr = 9.5;
236  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate18Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
237  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.623, 0.001, "Not equal within tolerance");
238  snr = 10.5;
239  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate18Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
240  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.985, 0.001, "Not equal within tolerance");
241  snr = 11.5;
242  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate18Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
243  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.999, 0.001, "Not equal within tolerance");
244 
245  snr = 12.0;
246  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate24Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
247  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 2.22e-7, 1e-7, "Not equal within tolerance");
248  snr = 13.0;
249  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate24Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
250  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.495, 0.001, "Not equal within tolerance");
251  snr = 14.0;
252  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate24Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
253  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.974, 0.001, "Not equal within tolerance");
254  snr = 15.0;
255  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate24Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
256  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.999, 0.001, "Not equal within tolerance");
257 
258  snr = 15.5;
259  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate36Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
260  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.012, 0.001, "Not equal within tolerance");
261  snr = 16.5;
262  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate36Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
263  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.818, 0.001, "Not equal within tolerance");
264  snr = 17.5;
265  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate36Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
266  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.993, 0.001, "Not equal within tolerance");
267  snr = 18.5;
268  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate36Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
269  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.999, 0.001, "Not equal within tolerance");
270 
271  snr = 20.0;
272  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate48Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
273  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 1.3e-4, 1e-4, "Not equal within tolerance");
274  snr = 21.0;
275  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate48Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
276  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.649, 0.001, "Not equal within tolerance");
277  snr = 22.0;
278  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate48Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
279  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.983, 0.001, "Not equal within tolerance");
280  snr = 23.0;
281  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate48Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
282  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.999, 0.001, "Not equal within tolerance");
283 
284  snr = 21.0;
285  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate54Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
286  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 5.44e-8, 1e-8, "Not equal within tolerance");
287  snr = 22.0;
288  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate54Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
289  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.410, 0.001, "Not equal within tolerance");
290  snr = 23.0;
291  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate54Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
292  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.958, 0.001, "Not equal within tolerance");
293  snr = 24.0;
294  ps = nist->GetChunkSuccessRate (WifiMode ("OfdmRate54Mbps"), txVector, std::pow (10.0, snr / 10.0), frameSize * 8);
295  NS_TEST_ASSERT_MSG_EQ_TOL (ps, 0.999, 0.001, "Not equal within tolerance");
296 }
297 
299 {
300 public:
301  using InterferenceHelper::InterferenceHelper;
302  using InterferenceHelper::CalculateChunkSuccessRate;
303  using InterferenceHelper::CalculateSnr;
304 };
305 
313 {
314 public:
317 
318 private:
319  virtual void DoRun (void);
320 };
321 
323  : TestCase ("WifiErrorRateModel test case MIMO")
324 {
325 }
326 
328 {
329 }
330 
331 void
333 {
334  TestInterferenceHelper interference;
335  interference.SetNoiseFigure (0);
336  WifiMode mode = WifiPhy::GetHtMcs0 ();
337  WifiTxVector txVector;
338 
339  txVector.SetMode (mode);
340  txVector.SetTxPowerLevel (0);
341  txVector.SetChannelWidth (20);
342  txVector.SetNss (1);
343  txVector.SetNTx (1);
344 
345  interference.SetNumberOfReceiveAntennas (1);
346  Ptr<NistErrorRateModel> nist = CreateObject<NistErrorRateModel> ();
347  interference.SetErrorRateModel (nist);
348 
349  // SISO: initial SNR set to 4dB
350  double initialSnr = 4.0;
351  double snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
352  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "Attempt to set initial SNR to known value failed");
353  Time duration = MilliSeconds (2);
354  double chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
355  NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, 0.905685, 0.000001, "CSR not within tolerance for SISO");
356  double sisoChunkSuccess = chunkSuccess;
357 
358  // MIMO 2x1:2: expect no SNR gain in AWGN channel
359  txVector.SetNss (2);
360  txVector.SetNTx (2);
361  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
362  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 2x1:2 MIMO");
363  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
364  NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, 0.905685, 0.000001, "CSR not within tolerance for SISO");
365 
366  // MIMO 1x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO thanks to RX diversity
367  txVector.SetNss (1);
368  txVector.SetNTx (1);
369  interference.SetNumberOfReceiveAntennas (2);
370  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
371  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not within tolerance for 1x2:1 MIMO");
372  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
373  NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 1x2:1 MIMO");
374 
375  // MIMO 2x2:1: expect that SNR is increased by a factor of 3 dB (10 log 2/1) compared to SISO thanks to RX diversity
376  txVector.SetNss (1);
377  txVector.SetNTx (2);
378  interference.SetNumberOfReceiveAntennas (2);
379  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
380  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not equal within tolerance for 2x2:1 MIMO");
381  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
382  NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 2x2:1 MIMO");
383 
384  // MIMO 2x2:2: expect no SNR gain in AWGN channel
385  txVector.SetNss (2);
386  txVector.SetNTx (2);
387  interference.SetNumberOfReceiveAntennas (2);
388  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
389  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not equal within tolerance for 2x2:2 MIMO");
390  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
391  NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not within tolerance for 2x2:2 MIMO");
392 
393  // MIMO 3x3:1: expect that SNR is increased by a factor of 4.8 dB (10 log 3/1) compared to SISO thanks to RX diversity
394  txVector.SetNss (1);
395  txVector.SetNTx (3);
396  interference.SetNumberOfReceiveAntennas (3);
397  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
398  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 4.8, 0.1, "SNR not within tolerance for 3x3:1 MIMO");
399  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
400  NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 3x3:1 MIMO");
401 
402  // MIMO 3x3:2: expect that SNR is increased by a factor of 1.8 dB (10 log 3/2) compared to SISO thanks to RX diversity
403  txVector.SetNss (2);
404  txVector.SetNTx (3);
405  interference.SetNumberOfReceiveAntennas (3);
406  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
407  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 1.8, 0.1, "SNR not within tolerance for 3x3:2 MIMO");
408  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
409  NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 3x3:2 MIMO");
410 
411  // MIMO 3x3:3: expect no SNR gain in AWGN channel
412  txVector.SetNss (3);
413  txVector.SetNTx (3);
414  interference.SetNumberOfReceiveAntennas (3);
415  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
416  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 3x3:3 MIMO");
417  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
418  NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not equal within tolerance for 3x3:3 MIMO");
419 
420  // MIMO 4x4:1: expect that SNR is increased by a factor of 6 dB (10 log 4/1) compared to SISO thanks to RX diversity
421  txVector.SetNss (1);
422  txVector.SetNTx (4);
423  interference.SetNumberOfReceiveAntennas (4);
424  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
425  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 6, 0.1, "SNR not within tolerance for 4x4:1 MIMO");
426  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
427  NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:1 MIMO");
428 
429  // MIMO 4x4:2: expect that SNR is increased by a factor of 3 dB (10 log 4/2) compared to SISO thanks to RX diversity
430  txVector.SetNss (2);
431  txVector.SetNTx (4);
432  interference.SetNumberOfReceiveAntennas (4);
433  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
434  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not within tolerance for 4x4:2 MIMO");
435  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
436  NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:2 MIMO");
437 
438  // MIMO 4x4:3: expect that SNR is increased by a factor of 1.2 dB (10 log 4/3) compared to SISO thanks to RX diversity
439  txVector.SetNss (3);
440  txVector.SetNTx (4);
441  interference.SetNumberOfReceiveAntennas (4);
442  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
443  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 1.2, 0.1, "SNR not within tolerance for 4x4:3 MIMO");
444  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
445  NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:1 MIMO");
446 
447  // MIMO 4x4:4: expect no SNR gain in AWGN channel
448  txVector.SetNss (4);
449  txVector.SetNTx (4);
450  interference.SetNumberOfReceiveAntennas (4);
451  snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
452  NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 4x4:4 MIMO");
453  chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
454  NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not within tolerance for 4x4:4 MIMO");
455 }
456 
460 std::map<std::pair <uint8_t /* mcs */, uint32_t /* size */>, std::map<double /* snr */, double /* per */> > expectedTableValues =
461 {
462 /* MCS 0 - 1458 bytes */
463  {std::make_pair (0, 1458), {
464  {-4.0, 1.0},
465  {-3.5, 1.0},
466  {-3.0, 1.0},
467  {-2.5, 1.0},
468  {-2.0, 1.0},
469  {-1.5, 1.0},
470  {-1.0, 1.0},
471  {-0.5, 0.990175},
472  {0.0, 0.77713},
473  {0.5, 0.314965},
474  {1.0, 0.06643},
475  {1.5, 0.011625},
476  {2.0, 0.00155},
477  {2.5, 0.00025},
478  {3.0, 0.0},
479  {3.5, 0.0},
480  {4.0, 0.0},
481  {4.5, 0.0},
482  {5.0, 0.0},
483  {5.5, 0.0},
484  {6.0, 0.0},
485  {6.5, 0.0},
486  {7.0, 0.0},
487  {7.5, 0.0},
488  {8.0, 0.0},
489  {8.5, 0.0},
490  {9.0, 0.0},
491  {9.5, 0.0},
492  {10.0, 0.0},
493  {10.5, 0.0},
494  {11.0, 0.0},
495  {11.5, 0.0},
496  {12.0, 0.0},
497  {12.5, 0.0},
498  {13.0, 0.0},
499  {13.5, 0.0},
500  {14.0, 0.0},
501  {14.5, 0.0},
502  {15.0, 0.0},
503  {15.5, 0.0},
504  {16.0, 0.0},
505  {16.5, 0.0},
506  {17.0, 0.0},
507  {17.5, 0.0},
508  {18.0, 0.0},
509  {18.5, 0.0},
510  {19.0, 0.0},
511  {19.5, 0.0},
512  {20.0, 0.0},
513  {20.5, 0.0},
514  {21.0, 0.0},
515  {21.5, 0.0},
516  {22.0, 0.0},
517  {22.5, 0.0},
518  {23.0, 0.0},
519  {23.5, 0.0},
520  {24.0, 0.0},
521  {24.5, 0.0},
522  {25.0, 0.0},
523  {25.5, 0.0},
524  {26.0, 0.0},
525  {26.5, 0.0},
526  {27.0, 0.0},
527  {27.5, 0.0},
528  {28.0, 0.0},
529  {28.5, 0.0},
530  {29.0, 0.0},
531  {29.5, 0.0},
532  {30.0, 0.0},
533 
534  }},
535 /* MCS 0 - 32 bytes */
536  {std::make_pair (0, 32), {
537  {-4.0, 1.0},
538  {-3.5, 1.0},
539  {-3.0, 0.99751},
540  {-2.5, 0.96869},
541  {-2.0, 0.87939},
542  {-1.5, 0.603825},
543  {-1.0, 0.34749},
544  {-0.5, 0.12408},
545  {0.0, 0.03774},
546  {0.5, 0.009915},
547  {1.0, 0.00220},
548  {1.5, 0.00036},
549  {2.0, 0.00007},
550  {2.5, 0.0},
551  {3.0, 0.0},
552  {3.5, 0.0},
553  {4.0, 0.0},
554  {4.5, 0.0},
555  {5.0, 0.0},
556  {5.5, 0.0},
557  {6.0, 0.0},
558  {6.5, 0.0},
559  {7.0, 0.0},
560  {7.5, 0.0},
561  {8.0, 0.0},
562  {8.5, 0.0},
563  {9.0, 0.0},
564  {9.5, 0.0},
565  {10.0, 0.0},
566  {10.5, 0.0},
567  {11.0, 0.0},
568  {11.5, 0.0},
569  {12.0, 0.0},
570  {12.5, 0.0},
571  {13.0, 0.0},
572  {13.5, 0.0},
573  {14.0, 0.0},
574  {14.5, 0.0},
575  {15.0, 0.0},
576  {15.5, 0.0},
577  {16.0, 0.0},
578  {16.5, 0.0},
579  {17.0, 0.0},
580  {17.5, 0.0},
581  {18.0, 0.0},
582  {18.5, 0.0},
583  {19.0, 0.0},
584  {19.5, 0.0},
585  {20.0, 0.0},
586  {20.5, 0.0},
587  {21.0, 0.0},
588  {21.5, 0.0},
589  {22.0, 0.0},
590  {22.5, 0.0},
591  {23.0, 0.0},
592  {23.5, 0.0},
593  {24.0, 0.0},
594  {24.5, 0.0},
595  {25.0, 0.0},
596  {25.5, 0.0},
597  {26.0, 0.0},
598  {26.5, 0.0},
599  {27.0, 0.0},
600  {27.5, 0.0},
601  {28.0, 0.0},
602  {28.5, 0.0},
603  {29.0, 0.0},
604  {29.5, 0.0},
605  {30.0, 0.0},
606  }},
607 /* MCS 0 - 1000 bytes */
608  {std::make_pair (0, 1000), {
609  {-4.0, 1.0},
610  {-3.5, 1.0},
611  {-3.0, 1.0},
612  {-2.5, 1.0},
613  {-2.0, 1.0},
614  {-1.5, 1.0},
615  {-1.0, 1.0},
616  {-0.5, 0.958024},
617  {0.0, 0.642853},
618  {0.5, 0.228528},
619  {1.0, 0.046052},
620  {1.5, 0.007988},
621  {2.0, 0.001063},
622  {2.5, 0.000171},
623  {3.0, 0.0},
624  {3.5, 0.0},
625  {4.0, 0.0},
626  {4.5, 0.0},
627  {5.0, 0.0},
628  {5.5, 0.0},
629  {6.0, 0.0},
630  {6.5, 0.0},
631  {7.0, 0.0},
632  {7.5, 0.0},
633  {8.0, 0.0},
634  {8.5, 0.0},
635  {9.0, 0.0},
636  {9.5, 0.0},
637  {10.0, 0.0},
638  {10.5, 0.0},
639  {11.0, 0.0},
640  {11.5, 0.0},
641  {12.0, 0.0},
642  {12.5, 0.0},
643  {13.0, 0.0},
644  {13.5, 0.0},
645  {14.0, 0.0},
646  {14.5, 0.0},
647  {15.0, 0.0},
648  {15.5, 0.0},
649  {16.0, 0.0},
650  {16.5, 0.0},
651  {17.0, 0.0},
652  {17.5, 0.0},
653  {18.0, 0.0},
654  {18.5, 0.0},
655  {19.0, 0.0},
656  {19.5, 0.0},
657  {20.0, 0.0},
658  {20.5, 0.0},
659  {21.0, 0.0},
660  {21.5, 0.0},
661  {22.0, 0.0},
662  {22.5, 0.0},
663  {23.0, 0.0},
664  {23.5, 0.0},
665  {24.0, 0.0},
666  {24.5, 0.0},
667  {25.0, 0.0},
668  {25.5, 0.0},
669  {26.0, 0.0},
670  {26.5, 0.0},
671  {27.0, 0.0},
672  {27.5, 0.0},
673  {28.0, 0.0},
674  {28.5, 0.0},
675  {29.0, 0.0},
676  {29.5, 0.0},
677  {30.0, 0.0},
678  }},
679 /* MCS 0 - 1 byte */
680  {std::make_pair (0, 1), {
681  {-4.0, 1.0},
682  {-3.5, 1.0},
683  {-3.0, 0.170854},
684  {-2.5, 0.102592},
685  {-2.0, 0.063963},
686  {-1.5, 0.028520},
687  {-1.0, 0.013253},
688  {-0.5, 0.004131},
689  {0.0, 0.001201},
690  {0.5, 0.000311},
691  {1.0, 0.000069},
692  {1.5, 0.000011},
693  {2.0, 0.000002},
694  {2.5, 0.0},
695  {3.0, 0.0},
696  {3.5, 0.0},
697  {4.0, 0.0},
698  {4.5, 0.0},
699  {5.0, 0.0},
700  {5.5, 0.0},
701  {6.0, 0.0},
702  {6.5, 0.0},
703  {7.0, 0.0},
704  {7.5, 0.0},
705  {8.0, 0.0},
706  {8.5, 0.0},
707  {9.0, 0.0},
708  {9.5, 0.0},
709  {10.0, 0.0},
710  {10.5, 0.0},
711  {11.0, 0.0},
712  {11.5, 0.0},
713  {12.0, 0.0},
714  {12.5, 0.0},
715  {13.0, 0.0},
716  {13.5, 0.0},
717  {14.0, 0.0},
718  {14.5, 0.0},
719  {15.0, 0.0},
720  {15.5, 0.0},
721  {16.0, 0.0},
722  {16.5, 0.0},
723  {17.0, 0.0},
724  {17.5, 0.0},
725  {18.0, 0.0},
726  {18.5, 0.0},
727  {19.0, 0.0},
728  {19.5, 0.0},
729  {20.0, 0.0},
730  {20.5, 0.0},
731  {21.0, 0.0},
732  {21.5, 0.0},
733  {22.0, 0.0},
734  {22.5, 0.0},
735  {23.0, 0.0},
736  {23.5, 0.0},
737  {24.0, 0.0},
738  {24.5, 0.0},
739  {25.0, 0.0},
740  {25.5, 0.0},
741  {26.0, 0.0},
742  {26.5, 0.0},
743  {27.0, 0.0},
744  {27.5, 0.0},
745  {28.0, 0.0},
746  {28.5, 0.0},
747  {29.0, 0.0},
748  {29.5, 0.0},
749  {30.0, 0.0},
750  }},
751 /* MCS 0 - 2000 bytes */
752  {std::make_pair (0, 2000), {
753  {-4.0, 1.0},
754  {-3.5, 1.0},
755  {-3.0, 1.0},
756  {-2.5, 1.0},
757  {-2.0, 1.0},
758  {-1.5, 1.0},
759  {-1.0, 1.0},
760  {-0.5, 0.998238},
761  {0.0, 0.872446},
762  {0.5, 0.404831},
763  {1.0, 0.089984},
764  {1.5, 0.015912},
765  {2.0, 0.002126},
766  {2.5, 0.000343},
767  {3.0, 0.0},
768  {3.5, 0.0},
769  {4.0, 0.0},
770  {4.5, 0.0},
771  {5.0, 0.0},
772  {5.5, 0.0},
773  {6.0, 0.0},
774  {6.5, 0.0},
775  {7.0, 0.0},
776  {7.5, 0.0},
777  {8.0, 0.0},
778  {8.5, 0.0},
779  {9.0, 0.0},
780  {9.5, 0.0},
781  {10.0, 0.0},
782  {10.5, 0.0},
783  {11.0, 0.0},
784  {11.5, 0.0},
785  {12.0, 0.0},
786  {12.5, 0.0},
787  {13.0, 0.0},
788  {13.5, 0.0},
789  {14.0, 0.0},
790  {14.5, 0.0},
791  {15.0, 0.0},
792  {15.5, 0.0},
793  {16.0, 0.0},
794  {16.5, 0.0},
795  {17.0, 0.0},
796  {17.5, 0.0},
797  {18.0, 0.0},
798  {18.5, 0.0},
799  {19.0, 0.0},
800  {19.5, 0.0},
801  {20.0, 0.0},
802  {20.5, 0.0},
803  {21.0, 0.0},
804  {21.5, 0.0},
805  {22.0, 0.0},
806  {22.5, 0.0},
807  {23.0, 0.0},
808  {23.5, 0.0},
809  {24.0, 0.0},
810  {24.5, 0.0},
811  {25.0, 0.0},
812  {25.5, 0.0},
813  {26.0, 0.0},
814  {26.5, 0.0},
815  {27.0, 0.0},
816  {27.5, 0.0},
817  {28.0, 0.0},
818  {28.5, 0.0},
819  {29.0, 0.0},
820  {29.5, 0.0},
821  {30.0, 0.0},
822  }},
823 /* MCS 7 - 1500 bytes */
824  {std::make_pair (7, 1500), {
825  {-4.0, 1.0},
826  {-3.5, 1.0},
827  {-3.0, 1.0},
828  {-2.5, 1.0},
829  {-2.0, 1.0},
830  {-1.5, 1.0},
831  {-1.0, 1.0},
832  {-0.5, 1.0},
833  {0.0, 1.0},
834  {0.5, 1.0},
835  {1.0, 1.0},
836  {1.5, 1.0},
837  {2.0, 1.0},
838  {2.5, 1.0},
839  {3.0, 1.0},
840  {3.5, 1.0},
841  {4.0, 1.0},
842  {4.5, 1.0},
843  {5.0, 1.0},
844  {5.5, 1.0},
845  {6.0, 1.0},
846  {6.5, 1.0},
847  {7.0, 1.0},
848  {7.5, 1.0},
849  {8.0, 1.0},
850  {8.5, 1.0},
851  {9.0, 1.0},
852  {9.5, 1.0},
853  {10.0, 1.0},
854  {10.5, 1.0},
855  {11.0, 1.0},
856  {11.5, 1.0},
857  {12.0, 1.0},
858  {12.5, 1.0},
859  {13.0, 1.0},
860  {13.5, 1.0},
861  {14.0, 1.0},
862  {14.5, 1.0},
863  {15.0, 1.0},
864  {15.5, 1.0},
865  {16.0, 1.0},
866  {16.5, 1.0},
867  {17.0, 1.0},
868  {17.5, 1.0},
869  {18.0, 0.984736},
870  {18.5, 0.730776},
871  {19.0, 0.336353},
872  {19.5, 0.121723},
873  {20.0, 0.035373},
874  {20.5, 0.010292},
875  {21.0, 0.002932},
876  {21.5, 0.000669},
877  {22.0, 0.000103},
878  {22.5, 0.000026},
879  {23.0, 0.0},
880  {23.5, 0.0},
881  {24.0, 0.0},
882  {24.5, 0.0},
883  {25.0, 0.0},
884  {25.5, 0.0},
885  {26.0, 0.0},
886  {26.5, 0.0},
887  {27.0, 0.0},
888  {27.5, 0.0},
889  {28.0, 0.0},
890  {28.5, 0.0},
891  {29.0, 0.0},
892  {29.5, 0.0},
893  {30.0, 0.0},
894  }},
895 /* MCS 8 - 1500 bytes */
896  {std::make_pair (8, 1500), {
897  {-4.0, 1.0},
898  {-3.5, 1.0},
899  {-3.0, 1.0},
900  {-2.5, 1.0},
901  {-2.0, 1.0},
902  {-1.5, 1.0},
903  {-1.0, 1.0},
904  {-0.5, 1.0},
905  {0.0, 1.0},
906  {0.5, 1.0},
907  {1.0, 1.0},
908  {1.5, 1.0},
909  {2.0, 1.0},
910  {2.5, 1.0},
911  {3.0, 1.0},
912  {3.5, 1.0},
913  {4.0, 1.0},
914  {4.5, 1.0},
915  {5.0, 1.0},
916  {5.5, 1.0},
917  {6.0, 1.0},
918  {6.5, 1.0},
919  {7.0, 1.0},
920  {7.5, 1.0},
921  {8.0, 1.0},
922  {8.5, 1.0},
923  {9.0, 1.0},
924  {9.5, 1.0},
925  {10.0, 1.0},
926  {10.5, 1.0},
927  {11.0, 1.0},
928  {11.5, 1.0},
929  {12.0, 1.0},
930  {12.5, 1.0},
931  {13.0, 1.0},
932  {13.5, 1.0},
933  {14.0, 1.0},
934  {14.5, 1.0},
935  {15.0, 1.0},
936  {15.5, 1.0},
937  {16.0, 1.0},
938  {16.5, 1.0},
939  {17.0, 1.0},
940  {17.5, 1.0},
941  {18.0, 1.0},
942  {18.5, 1.0},
943  {19.0, 1.0},
944  {19.5, 1.0},
945  {20.0, 1.0},
946  {20.5, 1.0},
947  {21.0, 0.993549},
948  {21.5, 0.941462},
949  {22.0, 0.689994},
950  {22.5, 0.408435},
951  {23.0, 0.198900},
952  {23.5, 0.086112},
953  {24.0, 0.035569},
954  {24.5, 0.014951},
955  {25.0, 0.005864},
956  {25.5, 0.002459},
957  {26.0, 0.001029},
958  {26.5, 0.000592},
959  {27.0, 0.000206},
960  {27.5, 0.0},
961  {28.0, 0.0},
962  {28.5, 0.0},
963  {29.0, 0.0},
964  {29.5, 0.0},
965  {30.0, 0.0},
966  }},
967 };
968 
976 {
977 public:
985  TableBasedErrorRateTestCase (const std::string &testName, WifiMode mode, uint32_t size);
986  virtual ~TableBasedErrorRateTestCase ();
987 
988 private:
989  virtual void DoRun (void);
990 
991  std::string m_testName;
993  uint32_t m_size;
994 };
995 
996 TableBasedErrorRateTestCase::TableBasedErrorRateTestCase (const std::string &testName, WifiMode mode, uint32_t size)
997  : TestCase (testName),
998  m_testName (testName),
999  m_mode (mode),
1000  m_size (size)
1001 {
1002 }
1003 
1005 {
1006 }
1007 
1008 void
1010 {
1011  //LogComponentEnable ("WifiErrorRateModelsTest", LOG_LEVEL_ALL);
1012  //LogComponentEnable ("TableBasedErrorRateModel", LOG_LEVEL_ALL);
1013  //LogComponentEnable ("YansErrorRateModel", LOG_LEVEL_ALL);
1014 
1015  Ptr<TableBasedErrorRateModel> table = CreateObject<TableBasedErrorRateModel> ();
1016  WifiTxVector txVector;
1017  txVector.SetMode (m_mode);
1018 
1019  // Spot test some values returned from TableBasedErrorRateModel
1020  for (double snr = -4.0; snr <= 30.0; snr += 0.5)
1021  {
1022  double expectedValue = 0;
1024  {
1025  Ptr<YansErrorRateModel> yans = CreateObject<YansErrorRateModel> ();
1026  expectedValue = 1 - yans->GetChunkSuccessRate (m_mode, txVector, std::pow (10.0, snr / 10.0), m_size * 8);
1027  }
1028  else
1029  {
1030  auto it = expectedTableValues.find (std::make_pair (m_mode.GetMcsValue (), m_size));
1031  if (it != expectedTableValues.end ())
1032  {
1033  auto itValue = it->second.find (snr);
1034  if (itValue != it->second.end ())
1035  {
1036  expectedValue = itValue->second;
1037  }
1038  else
1039  {
1040  NS_FATAL_ERROR ("SNR value not found!");
1041  }
1042  }
1043  else
1044  {
1045  NS_FATAL_ERROR ("No expected value found for the combination MCS " << +m_mode.GetMcsValue () << " and size " << m_size << " bytes");
1046  }
1047  }
1048  double per = 1 - table->GetChunkSuccessRate (m_mode, txVector, std::pow (10.0, snr / 10.0), m_size * 8);
1049  NS_LOG_INFO (m_testName << ": snr=" << snr << "dB per=" << per << " expectedPER=" << expectedValue);
1050  NS_TEST_ASSERT_MSG_EQ_TOL (per, expectedValue, 1e-6, "Not equal within tolerance");
1051  }
1052 }
1053 
1061 {
1062 public:
1064 };
1065 
1067  : TestSuite ("wifi-error-rate-models", UNIT)
1068 {
1069  AddTestCase (new WifiErrorRateModelsTestCaseDsss, TestCase::QUICK);
1070  AddTestCase (new WifiErrorRateModelsTestCaseNist, TestCase::QUICK);
1071  AddTestCase (new WifiErrorRateModelsTestCaseMimo, TestCase::QUICK);
1072  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedHtMcs0-1458bytes", WifiPhy::GetHtMcs0 (), 1458), TestCase::QUICK);
1073  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedHtMcs0-32bytes", WifiPhy::GetHtMcs0 (), 32), TestCase::QUICK);
1074  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedHtMcs0-1000bytes", WifiPhy::GetHtMcs0 (), 1000), TestCase::QUICK);
1075  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedHtMcs0-1byte", WifiPhy::GetHtMcs0 (), 1), TestCase::QUICK);
1076  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedHtMcs0-2000bytes", WifiPhy::GetHtMcs0 (), 2000), TestCase::QUICK);
1077  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedHtMcs7-1500bytes", WifiPhy::GetHtMcs7 (), 1500), TestCase::QUICK);
1078  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedVhtMcs0-1458bytes", WifiPhy::GetVhtMcs0 (), 1458), TestCase::QUICK);
1079  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedVhtMcs0-32bytes", WifiPhy::GetVhtMcs0 (), 32), TestCase::QUICK);
1080  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedVhtMcs0-1000bytes", WifiPhy::GetVhtMcs0 (), 1000), TestCase::QUICK);
1081  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedVhtMcs0-1byte", WifiPhy::GetVhtMcs0 (), 1), TestCase::QUICK);
1082  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedVhtMcs0-2000bytes", WifiPhy::GetVhtMcs0 (), 2000), TestCase::QUICK);
1083  AddTestCase (new TableBasedErrorRateTestCase ("DefaultTableBasedVhtMcs8-1500bytes", WifiPhy::GetVhtMcs8 (), 1500), TestCase::QUICK);
1084  AddTestCase (new TableBasedErrorRateTestCase ("FallbackTableBasedHeMcs11-1458bytes", WifiPhy::GetHeMcs11 (), 1458), TestCase::QUICK);
1085 }
1086 
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
static double FromRss(double rssDbw)
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
static WifiErrorRateModelsTestSuite wifiErrorRateModelsTestSuite
the test suite
TableBasedErrorRateTestCase(const std::string &testName, WifiMode mode, uint32_t size)
Constructor.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
const uint8_t ERROR_TABLE_BCC_MAX_NUM_MCS
A suite of tests to run.
Definition: test.h:1343
handles interference calculations
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
#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
encapsulates test code
Definition: test.h:1153
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
virtual void DoRun(void)
Implementation to actually run this TestCase.
Wifi Table-based Error Rate Models Test Case.
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode, WifiTxVector txVector) const
Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode. ...
uint32_t m_size
The size (in bytes) to test.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
std::map< std::pair< uint8_t, uint32_t >, std::map< double, double > > expectedTableValues
map of PER values that have been manually computed for a given MCS, size (in bytes) and SNR (in dB) i...
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition: test.h:378
std::string m_testName
The name of the test to run.
void SetNss(uint8_t nss)
Sets the number of Nss.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiMode m_mode
The WifiMode to test.
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
double DbToRatio(double dB)
Convert from dB to ratio.
Definition: wifi-utils.cc:35
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:53
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
double GetChunkSuccessRate(WifiMode mode, WifiTxVector txVector, double snr, uint64_t nbits) const
This method returns the probability that the given &#39;chunk&#39; of the packet will be successfully receive...
Wifi Error Rate Models Test Case MIMO.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void SetNoiseFigure(double value)
Set the noise figure.
Wifi Error Rate Models Test Case Nist.
double CalculateSnr(Ptr< Event > event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
Calculate the SNIR for the event (starting from now until the event end).
uint16_t GetChannelWidth(void) const
Wifi Error Rate Models Test Suite.
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:995
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:458
Wifi Error Rate Models Test Case Dsss.