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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Gary Pei <guangyu.pei@boeing.com>
18 */
19
45#ifndef DOXYGEN_SHOULD_SKIP_THIS
46
47#include <gsl/gsl_cdf.h>
48#include <gsl/gsl_integration.h>
49#include <gsl/gsl_math.h>
50#include <gsl/gsl_sf_bessel.h>
51
52#define min(a, b) ((a) < (b) ? (a) : (b))
53#define max(a, b) ((a) > (b) ? (a) : (b))
54#define WLAN_SIR_perfect 10.0 // if SIR > 10dB, perfect reception
55#define WLAN_SIR_impossible 0.1 // if SIR < -10dB, impossible to receive
56
57typedef struct fn_parameter_t
58{
59 double beta;
60 double n;
61} fn_parameters;
62
63double
64QFunction(double x)
65{
66 return 0.5 * erfc(x / sqrt(2.0));
67}
68
69double
70f(double x, void* params)
71{
72 double beta = ((fn_parameters*)params)->beta;
73 double n = ((fn_parameters*)params)->n;
74 double f =
75 pow(2 * gsl_cdf_ugaussian_P(x + beta) - 1, n - 1) * exp(-x * x / 2.0) / sqrt(2.0 * M_PI);
76 return f;
77}
78
79double
80p_e2(double e2)
81{
82 double sep;
83 double error;
84 fn_parameters params;
85 params.beta = sqrt(2.0 * e2);
86 params.n = 8.0;
87 gsl_integration_workspace* w = gsl_integration_workspace_alloc(1000);
88 gsl_function F;
89 F.function = &f;
90 F.params = &params;
91 gsl_integration_qagiu(&F, -params.beta, 0, 1e-7, 1000, w, &sep, &error);
92 gsl_integration_workspace_free(w);
93 if (error == 0.0)
94 {
95 sep = 1.0;
96 }
97 return 1.0 - sep;
98}
99
100double
101p_e1(double e1)
102{
103 return 1.0 - pow(1.0 - p_e2(e1 / 2.0), 2.0);
104}
105
106double
107DbToNoneDb(double x)
108{
109 return pow(10.0, x / 10.0);
110}
111
112double
113NoneDbToDb(double x)
114{
115 return 10.0 * log10(x);
116}
117
118double
119DQPSKFunction(double x)
120{
121 double pi = acos(-1.0);
122 return ((sqrt(2.0) + 1.0) / sqrt(8.0 * pi * sqrt(2.0))) * (1.0 / sqrt(x)) *
123 exp(-(2.0 - sqrt(2.0)) * x);
124}
125
126double
127Get80211bDsssDbpskBerIeee(double EcNc)
128{
129 double ber;
130 if (EcNc > WLAN_SIR_perfect)
131 {
132 ber = 0;
133 }
134 else if (EcNc < WLAN_SIR_impossible)
135 {
136 ber = 0.5;
137 }
138 else
139 {
140 ber = min(QFunction(sqrt(11.0 * EcNc)), 0.5);
141 }
142 return ber;
143}
144
145double
146Get80211bDsssDbpskBer(double sinr)
147{
148 double EbN0 = sinr * 22000000.0 / 1000000.0;
149 double ber = 0.5 * exp(-EbN0);
150 return ber;
151}
152
153double
154Get80211bDsssDqpskBerIeee(double EcNc)
155{
156 double ber;
157 if (EcNc > WLAN_SIR_perfect)
158 {
159 ber = 0;
160 }
161 else if (EcNc < WLAN_SIR_impossible)
162 {
163 ber = 0.5;
164 }
165 else
166 {
167 ber = min(QFunction(sqrt(5.5 * EcNc)), 0.5);
168 }
169 return ber;
170}
171
172double
173Get80211bDsssDqpskBer(double sinr)
174{
175 // 2 bits per symbol, 1 MSPS
176 double EbN0 = sinr * 22000000.0 / 1000000.0 / 2.0;
177 double ber = DQPSKFunction(EbN0);
178 return ber;
179}
180
181double
182Get80211bDsssDqpskCCK5_5BerIeee(double EcNc)
183{
184 double ber;
185 if (EcNc > WLAN_SIR_perfect)
186 {
187 ber = 0.0;
188 }
189 else if (EcNc < WLAN_SIR_impossible)
190 {
191 ber = 0.5;
192 }
193 else
194 {
195 double pew = 14.0 * QFunction(sqrt(EcNc * 8.0)) + QFunction(sqrt(EcNc * 16.0));
196 pew = min(pew, 0.99999);
197 ber = 8.0 / 15.0 * pew;
198 }
199 return ber;
200}
201
202double
203Get80211bDsssDqpskCCK11BerIeee(double EcNc)
204{
205 double ber;
206 if (EcNc > WLAN_SIR_perfect)
207 {
208 ber = 0.0;
209 }
210 else if (EcNc < WLAN_SIR_impossible)
211 {
212 ber = 0.5;
213 }
214 else
215 {
216 double pew = 24.0 * QFunction(sqrt(EcNc * 4.0)) + 16.0 * QFunction(sqrt(EcNc * 6.0)) +
217 174.0 * QFunction(sqrt(EcNc * 8.0)) + 16.0 * QFunction(sqrt(EcNc * 10.0)) +
218 24.0 * QFunction(sqrt(EcNc * 12.0)) + QFunction(sqrt(EcNc * 16.0));
219 pew = min(pew, 0.99999);
220 ber = 128.0 / 255.0 * pew;
221 }
222 return ber;
223}
224
225int
226main(int argc, char* argv[])
227{
228 double rss, sinr;
229 double totalPkt = 200.0;
230 // double noise = 1.552058; // (dB) this noise figure value corresponds to
231 // -99 dBm noise floor reported in CMU paper
232 double noise = 7; // (dB) this noise figure value corresponds to the
233 // default in YansWifiPhy, and matches CMU testbed results
234 double EcNc, EbN01, EbN02, EbN05, EbN011;
235 double ieee1, ieee2, ieee5, ieee11;
236 double numBits = (1024. + 40. + 14.) * 8.;
237 double dbpsk, dqpsk, cck16, cck256, sepcck16, sepcck256;
238 noise = DbToNoneDb(noise) * 1.3803e-23 * 290.0 * 22000000;
239 for (rss = -102.0; rss <= -80.0; rss += 0.1)
240 {
241 sinr = DbToNoneDb(rss) / 1000.0 / noise;
242 EcNc = sinr * 22000000.0 / 11000000.0; // IEEE sir
243 EbN01 = sinr * 22000000.0 / 1000000.0;
244 // 2 bits per symbol, 1 MSPS
245 EbN02 = sinr * 22000000.0 / 1000000.0 / 2.0;
246 EbN05 = sinr * 22000000.0 / 1375000.0 / 4.0;
247 EbN011 = sinr * 22000000.0 / 1375000.0 / 8.0;
248 // 1=rss, 2=EcNc, 3=EbN01, 4=EbN02, 5=EBN05, 6=EbN011
249 printf("%g %g %g %g %g %g ",
250 rss,
251 NoneDbToDb(EcNc),
252 NoneDbToDb(EbN01),
253 NoneDbToDb(EbN02),
254 NoneDbToDb(EbN05),
255 NoneDbToDb(EbN011));
256 ieee1 = Get80211bDsssDbpskBerIeee(EcNc);
257 ieee2 = Get80211bDsssDqpskBerIeee(EcNc);
258 ieee5 = Get80211bDsssDqpskCCK5_5BerIeee(EcNc);
259 ieee11 = Get80211bDsssDqpskCCK11BerIeee(EcNc);
260 // 7=ber_ieee1, 8=ber_ieee2, 9=ber_ieee5, 10=ber_ieee11
261 printf(" %g %g %g %g ", ieee1, ieee2, ieee5, ieee11);
262 ieee1 = totalPkt * pow(1 - ieee1, numBits);
263 ieee2 = totalPkt * pow(1 - ieee2, numBits);
264 ieee5 = totalPkt * pow(1 - ieee5, numBits);
265 ieee11 = totalPkt * pow(1 - ieee11, numBits);
266 // 11=pkt_ieee1, 12=pkt_ieee2, 13=pkt_ieee5, 14=pkt_ieee11
267 printf(" %g %g %g %g ", ieee1, ieee2, ieee5, ieee11);
268 dbpsk = Get80211bDsssDbpskBer(sinr);
269 dqpsk = Get80211bDsssDqpskBer(sinr);
270 cck16 = max(0, 8.0 / 15.0 * p_e2(4.0 * EbN05 / 2.0));
271 cck256 = max(0, 128.0 / 255.0 * p_e1(8.0 * EbN011 / 2.0));
272 // 15=ber_dbpsk, 16=ber_dqpsk, 17=ber_cck16, 18=ber_cck256
273 printf(" %g %g %g %g ", dbpsk, dqpsk, cck16, cck256);
274 dbpsk = totalPkt * pow(1 - dbpsk, numBits);
275 dqpsk = totalPkt * pow(1 - dqpsk, numBits);
276 sepcck16 = p_e2(4.0 * EbN05 / 2.0);
277 sepcck256 = p_e1(8.0 * EbN011 / 2.0);
278 cck16 = totalPkt * pow(1.0 - sepcck16, numBits / 4.0);
279 cck256 = totalPkt * pow(1.0 - sepcck256, numBits / 8.0);
280 // 19=pkt_dbpsk, 20=pkt_dqpsk, 21=pkt_cck16, 22=pkt_cck256
281 printf(" %g %g %g %g ", dbpsk, dqpsk, cck16, cck256);
282 // 23=sinr
283 printf(" %g \n", NoneDbToDb(sinr));
284 }
285 return 0;
286}
287
288#endif /* DOXYGEN_SHOULD_SKIP_THIS */
FtrParams params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.