A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
80211b.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 The Boeing Company
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Gary Pei <guangyu.pei@boeing.com>
7 */
8
9/**
10 * @file
11 * @ingroup wifi-test
12 * @ingroup tests
13 *
14 * This program is used to generate plots found in the paper
15 * Guangyu Pei and Tom Henderson, "Validation of ns-3 802.11b PHY model",
16 * available online at http://www.nsnam.org/~pei/80211b.pdf
17 *
18 * It can be compiled as a C program and relies on a library installation of
19 * the GNU Scientific Library (gsl). To compile:
20 * gcc 80211b.c -o 80211b -lm -lgsl -lgslcblas
21 *
22 * The executable output should be redirected into a text file 80211b.txt
23 * ./80211b > 80211b.txt
24 *
25 * Then gnuplot can load the associated plot file which references 80211b.txt:
26 * gnuplot 80211b.plt
27 */
28
29/**
30 * @ingroup wifi
31 * @defgroup wifi-test wifi module tests
32 */
33
34#ifndef DOXYGEN_SHOULD_SKIP_THIS
35
36#include <gsl/gsl_cdf.h>
37#include <gsl/gsl_integration.h>
38#include <gsl/gsl_math.h>
39#include <gsl/gsl_sf_bessel.h>
40
41#define min(a, b) ((a) < (b) ? (a) : (b))
42#define max(a, b) ((a) > (b) ? (a) : (b))
43#define WLAN_SIR_perfect 10.0 // if SIR > 10dB, perfect reception
44#define WLAN_SIR_impossible 0.1 // if SIR < -10dB, impossible to receive
45
46typedef struct fn_parameter_t
47{
48 double beta; ///< beta
49 double n; ///< n
50} fn_parameters;
51
52double
53QFunction(double x)
54{
55 return 0.5 * erfc(x / sqrt(2.0));
56}
57
58double
59f(double x, void* params)
60{
61 double beta = ((fn_parameters*)params)->beta;
62 double n = ((fn_parameters*)params)->n;
63 double f =
64 pow(2 * gsl_cdf_ugaussian_P(x + beta) - 1, n - 1) * exp(-x * x / 2.0) / sqrt(2.0 * M_PI);
65 return f;
66}
67
68double
69p_e2(double e2)
70{
71 double sep;
72 double error;
73 fn_parameters params;
74 params.beta = sqrt(2.0 * e2);
75 params.n = 8.0;
76 gsl_integration_workspace* w = gsl_integration_workspace_alloc(1000);
77 gsl_function F;
78 F.function = &f;
79 F.params = &params;
80 gsl_integration_qagiu(&F, -params.beta, 0, 1e-7, 1000, w, &sep, &error);
81 gsl_integration_workspace_free(w);
82 if (error == 0.0)
83 {
84 sep = 1.0;
85 }
86 return 1.0 - sep;
87}
88
89double
90p_e1(double e1)
91{
92 return 1.0 - pow(1.0 - p_e2(e1 / 2.0), 2.0);
93}
94
95double
96DbToNoneDb(double x)
97{
98 return pow(10.0, x / 10.0);
99}
100
101double
102NoneDbToDb(double x)
103{
104 return 10.0 * log10(x);
105}
106
107double
108DQPSKFunction(double x)
109{
110 double pi = acos(-1.0);
111 return ((sqrt(2.0) + 1.0) / sqrt(8.0 * pi * sqrt(2.0))) * (1.0 / sqrt(x)) *
112 exp(-(2.0 - sqrt(2.0)) * x);
113}
114
115double
116Get80211bDsssDbpskBerIeee(double EcNc)
117{
118 double ber;
119 if (EcNc > WLAN_SIR_perfect)
120 {
121 ber = 0;
122 }
123 else if (EcNc < WLAN_SIR_impossible)
124 {
125 ber = 0.5;
126 }
127 else
128 {
129 ber = min(QFunction(sqrt(11.0 * EcNc)), 0.5);
130 }
131 return ber;
132}
133
134double
135Get80211bDsssDbpskBer(double sinr)
136{
137 double EbN0 = sinr * 22000000.0 / 1000000.0;
138 double ber = 0.5 * exp(-EbN0);
139 return ber;
140}
141
142double
143Get80211bDsssDqpskBerIeee(double EcNc)
144{
145 double ber;
146 if (EcNc > WLAN_SIR_perfect)
147 {
148 ber = 0;
149 }
150 else if (EcNc < WLAN_SIR_impossible)
151 {
152 ber = 0.5;
153 }
154 else
155 {
156 ber = min(QFunction(sqrt(5.5 * EcNc)), 0.5);
157 }
158 return ber;
159}
160
161double
162Get80211bDsssDqpskBer(double sinr)
163{
164 // 2 bits per symbol, 1 MSPS
165 double EbN0 = sinr * 22000000.0 / 1000000.0 / 2.0;
166 double ber = DQPSKFunction(EbN0);
167 return ber;
168}
169
170double
171Get80211bDsssDqpskCCK5_5BerIeee(double EcNc)
172{
173 double ber;
174 if (EcNc > WLAN_SIR_perfect)
175 {
176 ber = 0.0;
177 }
178 else if (EcNc < WLAN_SIR_impossible)
179 {
180 ber = 0.5;
181 }
182 else
183 {
184 double pew = 14.0 * QFunction(sqrt(EcNc * 8.0)) + QFunction(sqrt(EcNc * 16.0));
185 pew = min(pew, 0.99999);
186 ber = 8.0 / 15.0 * pew;
187 }
188 return ber;
189}
190
191double
192Get80211bDsssDqpskCCK11BerIeee(double EcNc)
193{
194 double ber;
195 if (EcNc > WLAN_SIR_perfect)
196 {
197 ber = 0.0;
198 }
199 else if (EcNc < WLAN_SIR_impossible)
200 {
201 ber = 0.5;
202 }
203 else
204 {
205 double pew = 24.0 * QFunction(sqrt(EcNc * 4.0)) + 16.0 * QFunction(sqrt(EcNc * 6.0)) +
206 174.0 * QFunction(sqrt(EcNc * 8.0)) + 16.0 * QFunction(sqrt(EcNc * 10.0)) +
207 24.0 * QFunction(sqrt(EcNc * 12.0)) + QFunction(sqrt(EcNc * 16.0));
208 pew = min(pew, 0.99999);
209 ber = 128.0 / 255.0 * pew;
210 }
211 return ber;
212}
213
214int
215main(int argc, char* argv[])
216{
217 double rss, sinr;
218 double totalPkt = 200.0;
219 // double noise = 1.552058; // (dB) this noise figure value corresponds to
220 // -99 dBm noise floor reported in CMU paper
221 double noise = 7; // (dB) this noise figure value corresponds to the
222 // default in YansWifiPhy, and matches CMU testbed results
223 double EcNc, EbN01, EbN02, EbN05, EbN011;
224 double ieee1, ieee2, ieee5, ieee11;
225 double numBits = (1024. + 40. + 14.) * 8.;
226 double dbpsk, dqpsk, cck16, cck256, sepcck16, sepcck256;
227 noise = DbToNoneDb(noise) * 1.3803e-23 * 290.0 * 22000000;
228 for (rss = -102.0; rss <= -80.0; rss += 0.1)
229 {
230 sinr = DbToNoneDb(rss) / 1000.0 / noise;
231 EcNc = sinr * 22000000.0 / 11000000.0; // IEEE sir
232 EbN01 = sinr * 22000000.0 / 1000000.0;
233 // 2 bits per symbol, 1 MSPS
234 EbN02 = sinr * 22000000.0 / 1000000.0 / 2.0;
235 EbN05 = sinr * 22000000.0 / 1375000.0 / 4.0;
236 EbN011 = sinr * 22000000.0 / 1375000.0 / 8.0;
237 // 1=rss, 2=EcNc, 3=EbN01, 4=EbN02, 5=EBN05, 6=EbN011
238 printf("%g %g %g %g %g %g ",
239 rss,
240 NoneDbToDb(EcNc),
241 NoneDbToDb(EbN01),
242 NoneDbToDb(EbN02),
243 NoneDbToDb(EbN05),
244 NoneDbToDb(EbN011));
245 ieee1 = Get80211bDsssDbpskBerIeee(EcNc);
246 ieee2 = Get80211bDsssDqpskBerIeee(EcNc);
247 ieee5 = Get80211bDsssDqpskCCK5_5BerIeee(EcNc);
248 ieee11 = Get80211bDsssDqpskCCK11BerIeee(EcNc);
249 // 7=ber_ieee1, 8=ber_ieee2, 9=ber_ieee5, 10=ber_ieee11
250 printf(" %g %g %g %g ", ieee1, ieee2, ieee5, ieee11);
251 ieee1 = totalPkt * pow(1 - ieee1, numBits);
252 ieee2 = totalPkt * pow(1 - ieee2, numBits);
253 ieee5 = totalPkt * pow(1 - ieee5, numBits);
254 ieee11 = totalPkt * pow(1 - ieee11, numBits);
255 // 11=pkt_ieee1, 12=pkt_ieee2, 13=pkt_ieee5, 14=pkt_ieee11
256 printf(" %g %g %g %g ", ieee1, ieee2, ieee5, ieee11);
257 dbpsk = Get80211bDsssDbpskBer(sinr);
258 dqpsk = Get80211bDsssDqpskBer(sinr);
259 cck16 = max(0, 8.0 / 15.0 * p_e2(4.0 * EbN05 / 2.0));
260 cck256 = max(0, 128.0 / 255.0 * p_e1(8.0 * EbN011 / 2.0));
261 // 15=ber_dbpsk, 16=ber_dqpsk, 17=ber_cck16, 18=ber_cck256
262 printf(" %g %g %g %g ", dbpsk, dqpsk, cck16, cck256);
263 dbpsk = totalPkt * pow(1 - dbpsk, numBits);
264 dqpsk = totalPkt * pow(1 - dqpsk, numBits);
265 sepcck16 = p_e2(4.0 * EbN05 / 2.0);
266 sepcck256 = p_e1(8.0 * EbN011 / 2.0);
267 cck16 = totalPkt * pow(1.0 - sepcck16, numBits / 4.0);
268 cck256 = totalPkt * pow(1.0 - sepcck256, numBits / 8.0);
269 // 19=pkt_dbpsk, 20=pkt_dqpsk, 21=pkt_cck16, 22=pkt_cck256
270 printf(" %g %g %g %g ", dbpsk, dqpsk, cck16, cck256);
271 // 23=sinr
272 printf(" %g \n", NoneDbToDb(sinr));
273 }
274 return 0;
275}
276
277#endif /* DOXYGEN_SHOULD_SKIP_THIS */
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.