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