A Discrete-Event Network Simulator
API
wifi-spectrum-value-helper.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2009 CTTC
4 * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
5 * Copyright (c) 2017 Orange Labs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation;
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Authors: Nicola Baldo <nbaldo@cttc.es>
21 * Giuseppe Piro <g.piro@poliba.it>
22 * Rediet <getachew.redieteab@orange.com>
23 */
24
25#include <map>
26#include <cmath>
28#include "ns3/log.h"
29#include "ns3/fatal-error.h"
30#include "ns3/assert.h"
31
32namespace ns3 {
33
34NS_LOG_COMPONENT_DEFINE ("WifiSpectrumValueHelper");
35
38{
46 WifiSpectrumModelId (uint32_t f, uint16_t w, double b, uint16_t g);
48 uint16_t m_channelWidth;
51};
52
53WifiSpectrumModelId::WifiSpectrumModelId (uint32_t f, uint16_t w, double b, uint16_t g)
54 : m_centerFrequency (f),
55 m_channelWidth (w),
56 m_bandBandwidth (b),
57 m_guardBandwidth (g)
58{
59 NS_LOG_FUNCTION (this << f << w << b << g);
60}
61
68bool
70{
76 && (a.m_bandBandwidth < b.m_bandBandwidth)) // to cover coexistence of 11ax with legacy case
80 && (a.m_guardBandwidth < b.m_guardBandwidth))); // to cover 2.4 GHz case, where DSSS coexists with OFDM
81}
82
83static std::map<WifiSpectrumModelId, Ptr<SpectrumModel> > g_wifiSpectrumModelMap;
84
86WifiSpectrumValueHelper::GetSpectrumModel (uint32_t centerFrequency, uint16_t channelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth)
87{
88 NS_LOG_FUNCTION (centerFrequency << channelWidth << bandBandwidth << guardBandwidth);
90 WifiSpectrumModelId key (centerFrequency, channelWidth, bandBandwidth, guardBandwidth);
91 std::map<WifiSpectrumModelId, Ptr<SpectrumModel> >::iterator it = g_wifiSpectrumModelMap.find (key);
92 if (it != g_wifiSpectrumModelMap.end ())
93 {
94 ret = it->second;
95 }
96 else
97 {
98 Bands bands;
99 double centerFrequencyHz = centerFrequency * 1e6;
100 double bandwidth = (channelWidth + (2.0 * guardBandwidth)) * 1e6;
101 // For OFDM, the center subcarrier is null (at center frequency)
102 uint32_t numBands = static_cast<uint32_t> ((bandwidth / bandBandwidth) + 0.5);
103 NS_ASSERT (numBands > 0);
104 if (numBands % 2 == 0)
105 {
106 // round up to the nearest odd number of subbands so that bands
107 // are symmetric around center frequency
108 numBands += 1;
109 }
110 NS_ASSERT_MSG (numBands % 2 == 1, "Number of bands should be odd");
111 NS_LOG_DEBUG ("Num bands " << numBands << " band bandwidth " << bandBandwidth);
112 // lay down numBands/2 bands symmetrically around center frequency
113 // and place an additional band at center frequency
114 double startingFrequencyHz = centerFrequencyHz - (numBands / 2 * bandBandwidth) - bandBandwidth / 2;
115 for (size_t i = 0; i < numBands; i++)
116 {
117 BandInfo info;
118 double f = startingFrequencyHz + (i * bandBandwidth);
119 info.fl = f;
120 f += bandBandwidth / 2;
121 info.fc = f;
122 f += bandBandwidth / 2;
123 info.fh = f;
124 NS_LOG_DEBUG ("creating band " << i << " (" << info.fl << ":" << info.fc << ":" << info.fh << ")");
125 bands.push_back (info);
126 }
127 ret = Create<SpectrumModel> (std::move (bands));
128 g_wifiSpectrumModelMap.insert (std::pair<WifiSpectrumModelId, Ptr<SpectrumModel> > (key, ret));
129 }
130 NS_LOG_LOGIC ("returning SpectrumModel::GetUid () == " << ret->GetUid ());
131 return ret;
132}
133
134// Power allocated to 71 center subbands out of 135 total subbands in the band
136WifiSpectrumValueHelper::CreateDsssTxPowerSpectralDensity (uint32_t centerFrequency, double txPowerW, uint16_t guardBandwidth)
137{
138 NS_LOG_FUNCTION (centerFrequency << txPowerW << +guardBandwidth);
139 uint16_t channelWidth = 22; // DSSS channels are 22 MHz wide
140 uint32_t bandBandwidth = 312500;
141 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequency, channelWidth, bandBandwidth, guardBandwidth));
142 Values::iterator vit = c->ValuesBegin ();
143 Bands::const_iterator bit = c->ConstBandsBegin ();
144 uint32_t nGuardBands = static_cast<uint32_t> (((2 * guardBandwidth * 1e6) / bandBandwidth) + 0.5);
145 uint32_t nAllocatedBands = static_cast<uint32_t> (((channelWidth * 1e6) / bandBandwidth) + 0.5);
146 NS_ASSERT (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nGuardBands + 1));
147 // Evenly spread power across 22 MHz
148 double txPowerPerBand = txPowerW / nAllocatedBands;
149 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++, bit++)
150 {
151 if ((i >= (nGuardBands / 2)) && (i <= ((nGuardBands / 2) + nAllocatedBands - 1)))
152 {
153 *vit = txPowerPerBand / (bit->fh - bit->fl);
154 }
155 }
156 return c;
157}
158
160WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity (uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth,
161 double minInnerBandDbr, double minOuterBandDbr, double lowestPointDbr)
162{
163 NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW << guardBandwidth << minInnerBandDbr << minOuterBandDbr << lowestPointDbr);
164 uint32_t bandBandwidth = 0;
165 uint32_t innerSlopeWidth = 0;
166 switch (channelWidth)
167 {
168 case 20:
169 bandBandwidth = 312500;
170 innerSlopeWidth = static_cast<uint32_t> ((2e6 / bandBandwidth) + 0.5); // [-11;-9] & [9;11]
171 break;
172 case 10:
173 bandBandwidth = 156250;
174 innerSlopeWidth = static_cast<uint32_t> ((1e6 / bandBandwidth) + 0.5); // [-5.5;-4.5] & [4.5;5.5]
175 break;
176 case 5:
177 bandBandwidth = 78125;
178 innerSlopeWidth = static_cast<uint32_t> ((5e5 / bandBandwidth) + 0.5); // [-2.75;-2.5] & [2.5;2.75]
179 break;
180 default:
181 NS_FATAL_ERROR ("Channel width " << channelWidth << " should be correctly set.");
182 return 0;
183 }
184
185 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequency, channelWidth, bandBandwidth, guardBandwidth));
186 uint32_t nGuardBands = static_cast<uint32_t> (((2 * guardBandwidth * 1e6) / bandBandwidth) + 0.5);
187 uint32_t nAllocatedBands = static_cast<uint32_t> (((channelWidth * 1e6) / bandBandwidth) + 0.5);
188 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nGuardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumBands ());
189 // 52 subcarriers (48 data + 4 pilot)
190 // skip guard band and 6 subbands, then place power in 26 subbands, then
191 // skip the center subband, then place power in 26 subbands, then skip
192 // the final 6 subbands and the guard band.
193 double txPowerPerBandW = txPowerW / 52;
194 NS_LOG_DEBUG ("Power per band " << txPowerPerBandW << "W");
195 uint32_t start1 = (nGuardBands / 2) + 6;
196 uint32_t stop1 = start1 + 26 - 1;
197 uint32_t start2 = stop1 + 2;
198 uint32_t stop2 = start2 + 26 - 1;
199
200 //Build transmit spectrum mask
201 std::vector <WifiSpectrumBand> subBands;
202 subBands.push_back (std::make_pair (start1, stop1));
203 subBands.push_back (std::make_pair (start2, stop2));
204 WifiSpectrumBand maskBand (0, nAllocatedBands + nGuardBands);
205 CreateSpectrumMaskForOfdm (c, subBands, maskBand,
206 txPowerPerBandW, nGuardBands,
207 innerSlopeWidth, minInnerBandDbr,
208 minOuterBandDbr, lowestPointDbr);
209 NormalizeSpectrumMask (c, txPowerW);
210 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation failed");
211 return c;
212}
213
215WifiSpectrumValueHelper::CreateHtOfdmTxPowerSpectralDensity (uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth,
216 double minInnerBandDbr, double minOuterBandDbr, double lowestPointDbr)
217{
218 NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW << guardBandwidth << minInnerBandDbr << minOuterBandDbr << lowestPointDbr);
219 uint32_t bandBandwidth = 312500;
220 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequency, channelWidth, bandBandwidth, guardBandwidth));
221 uint32_t nGuardBands = static_cast<uint32_t> (((2 * guardBandwidth * 1e6) / bandBandwidth) + 0.5);
222 uint32_t nAllocatedBands = static_cast<uint32_t> (((channelWidth * 1e6) / bandBandwidth) + 0.5);
223 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nGuardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumBands ());
224 double txPowerPerBandW = 0.0;
225 // skip the guard band and 4 subbands, then place power in 28 subbands, then
226 // skip the center subband, then place power in 28 subbands, then skip
227 // the final 4 subbands and the guard band.
228 // Repeat for each 20 MHz band.
229 uint32_t start1 = (nGuardBands / 2) + 4;
230 uint32_t stop1 = start1 + 28 - 1;
231 uint32_t start2 = stop1 + 2;
232 uint32_t stop2 = start2 + 28 - 1;
233 uint32_t start3 = stop2 + (2 * 4);
234 uint32_t stop3 = start3 + 28 - 1;
235 uint32_t start4 = stop3 + 2;
236 uint32_t stop4 = start4 + 28 - 1;
237 uint32_t start5 = stop4 + (2 * 4);
238 uint32_t stop5 = start5 + 28 - 1;
239 uint32_t start6 = stop5 + 2;
240 uint32_t stop6 = start6 + 28 - 1;
241 uint32_t start7 = stop6 + (2 * 4);
242 uint32_t stop7 = start7 + 28 - 1;
243 uint32_t start8 = stop7 + 2;
244 uint32_t stop8 = start8 + 28 - 1;
245 uint32_t start9 = stop8 + (2 * 4);
246 uint32_t stop9 = start9 + 28 - 1;
247 uint32_t start10 = stop9 + 2;
248 uint32_t stop10 = start10 + 28 - 1;
249 uint32_t start11 = stop10 + (2 * 4);
250 uint32_t stop11 = start11 + 28 - 1;
251 uint32_t start12 = stop11 + 2;
252 uint32_t stop12 = start12 + 28 - 1;
253 uint32_t start13 = stop12 + (2 * 4);
254 uint32_t stop13 = start13 + 28 - 1;
255 uint32_t start14 = stop13 + 2;
256 uint32_t stop14 = start14 + 28 - 1;
257 uint32_t start15 = stop14 + (2 * 4);
258 uint32_t stop15 = start15 + 28 - 1;
259 uint32_t start16 = stop15 + 2;
260 uint32_t stop16 = start16 + 28 - 1;
261 //Prepare spectrum mask specific variables
262 uint32_t innerSlopeWidth = static_cast<uint32_t> ((2e6 / bandBandwidth) + 0.5); //size in number of subcarriers of the inner band (2MHz for HT/VHT)
263 std::vector <WifiSpectrumBand> subBands; //list of data/pilot-containing subBands (sent at 0dBr)
264 WifiSpectrumBand maskBand (0, nAllocatedBands + nGuardBands);
265 switch (channelWidth)
266 {
267 case 20:
268 // 56 subcarriers (52 data + 4 pilot)
269 txPowerPerBandW = txPowerW / 56;
270 subBands.push_back (std::make_pair (start1, stop1));
271 subBands.push_back (std::make_pair (start2, stop2));
272 break;
273 case 40:
274 // 112 subcarriers (104 data + 8 pilot)
275 // possible alternative: 114 subcarriers (108 data + 6 pilot)
276 txPowerPerBandW = txPowerW / 112;
277 subBands.push_back (std::make_pair (start1, stop1));
278 subBands.push_back (std::make_pair (start2, stop2));
279 subBands.push_back (std::make_pair (start3, stop3));
280 subBands.push_back (std::make_pair (start4, stop4));
281 break;
282 case 80:
283 // 224 subcarriers (208 data + 16 pilot)
284 // possible alternative: 242 subcarriers (234 data + 8 pilot)
285 txPowerPerBandW = txPowerW / 224;
286 subBands.push_back (std::make_pair (start1, stop1));
287 subBands.push_back (std::make_pair (start2, stop2));
288 subBands.push_back (std::make_pair (start3, stop3));
289 subBands.push_back (std::make_pair (start4, stop4));
290 subBands.push_back (std::make_pair (start5, stop5));
291 subBands.push_back (std::make_pair (start6, stop6));
292 subBands.push_back (std::make_pair (start7, stop7));
293 subBands.push_back (std::make_pair (start8, stop8));
294 break;
295 case 160:
296 // 448 subcarriers (416 data + 32 pilot)
297 // possible alternative: 484 subcarriers (468 data + 16 pilot)
298 txPowerPerBandW = txPowerW / 448;
299 subBands.push_back (std::make_pair (start1, stop1));
300 subBands.push_back (std::make_pair (start2, stop2));
301 subBands.push_back (std::make_pair (start3, stop3));
302 subBands.push_back (std::make_pair (start4, stop4));
303 subBands.push_back (std::make_pair (start5, stop5));
304 subBands.push_back (std::make_pair (start6, stop6));
305 subBands.push_back (std::make_pair (start7, stop7));
306 subBands.push_back (std::make_pair (start8, stop8));
307 subBands.push_back (std::make_pair (start9, stop9));
308 subBands.push_back (std::make_pair (start10, stop10));
309 subBands.push_back (std::make_pair (start11, stop11));
310 subBands.push_back (std::make_pair (start12, stop12));
311 subBands.push_back (std::make_pair (start13, stop13));
312 subBands.push_back (std::make_pair (start14, stop14));
313 subBands.push_back (std::make_pair (start15, stop15));
314 subBands.push_back (std::make_pair (start16, stop16));
315 break;
316 }
317
318 //Build transmit spectrum mask
319 CreateSpectrumMaskForOfdm (c, subBands, maskBand,
320 txPowerPerBandW, nGuardBands,
321 innerSlopeWidth, minInnerBandDbr,
322 minOuterBandDbr, lowestPointDbr);
323 NormalizeSpectrumMask (c, txPowerW);
324 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation failed");
325 return c;
326}
327
329WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth,
330 double minInnerBandDbr, double minOuterBandDbr, double lowestPointDbr)
331{
332 NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW << guardBandwidth << minInnerBandDbr << minOuterBandDbr << lowestPointDbr);
333 uint32_t bandBandwidth = 78125;
334 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequency, channelWidth, bandBandwidth, guardBandwidth));
335 uint32_t nGuardBands = static_cast<uint32_t> (((2 * guardBandwidth * 1e6) / bandBandwidth) + 0.5);
336 uint32_t nAllocatedBands = static_cast<uint32_t> (((channelWidth * 1e6) / bandBandwidth) + 0.5);
337 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nGuardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumBands ());
338 double txPowerPerBandW = 0.0;
339 uint32_t start1;
340 uint32_t stop1;
341 uint32_t start2;
342 uint32_t stop2;
343 uint32_t start3;
344 uint32_t stop3;
345 uint32_t start4;
346 uint32_t stop4;
347 //Prepare spectrum mask specific variables
348 uint32_t innerSlopeWidth = static_cast<uint32_t> ((1e6 / bandBandwidth) + 0.5); //size in number of subcarriers of the inner band
349 std::vector <WifiSpectrumBand> subBands; //list of data/pilot-containing subBands (sent at 0dBr)
350 WifiSpectrumBand maskBand (0, nAllocatedBands + nGuardBands);
351 switch (channelWidth)
352 {
353 case 20:
354 // 242 subcarriers (234 data + 8 pilot)
355 txPowerPerBandW = txPowerW / 242;
356 innerSlopeWidth = static_cast<uint32_t> ((5e5 / bandBandwidth) + 0.5); // [-10.25;-9.75] & [9.75;10.25]
357 // skip the guard band and 6 subbands, then place power in 121 subbands, then
358 // skip 3 DC, then place power in 121 subbands, then skip
359 // the final 5 subbands and the guard band.
360 start1 = (nGuardBands / 2) + 6;
361 stop1 = start1 + 121 - 1;
362 start2 = stop1 + 4;
363 stop2 = start2 + 121 - 1;
364 subBands.push_back (std::make_pair (start1, stop1));
365 subBands.push_back (std::make_pair (start2, stop2));
366 break;
367 case 40:
368 // 484 subcarriers (468 data + 16 pilot)
369 txPowerPerBandW = txPowerW / 484;
370 // skip the guard band and 12 subbands, then place power in 242 subbands, then
371 // skip 5 DC, then place power in 242 subbands, then skip
372 // the final 11 subbands and the guard band.
373 start1 = (nGuardBands / 2) + 12;
374 stop1 = start1 + 242 - 1;
375 start2 = stop1 + 6;
376 stop2 = start2 + 242 - 1;
377 subBands.push_back (std::make_pair (start1, stop1));
378 subBands.push_back (std::make_pair (start2, stop2));
379 break;
380 case 80:
381 // 996 subcarriers (980 data + 16 pilot)
382 txPowerPerBandW = txPowerW / 996;
383 // skip the guard band and 12 subbands, then place power in 498 subbands, then
384 // skip 5 DC, then place power in 498 subbands, then skip
385 // the final 11 subbands and the guard band.
386 start1 = (nGuardBands / 2) + 12;
387 stop1 = start1 + 498 - 1;
388 start2 = stop1 + 6;
389 stop2 = start2 + 498 - 1;
390 subBands.push_back (std::make_pair (start1, stop1));
391 subBands.push_back (std::make_pair (start2, stop2));
392 break;
393 case 160:
394 // 2 x 996 subcarriers (2 x 80 MHZ bands)
395 txPowerPerBandW = txPowerW / (2 * 996);
396 start1 = (nGuardBands / 2) + 12;
397 stop1 = start1 + 498 - 1;
398 start2 = stop1 + 6;
399 stop2 = start2 + 498 - 1;
400 start3 = stop2 + (2 * 12);
401 stop3 = start3 + 498 - 1;
402 start4 = stop3 + 6;
403 stop4 = start4 + 498 - 1;
404 subBands.push_back (std::make_pair (start1, stop1));
405 subBands.push_back (std::make_pair (start2, stop2));
406 subBands.push_back (std::make_pair (start3, stop3));
407 subBands.push_back (std::make_pair (start4, stop4));
408 break;
409 default:
410 NS_FATAL_ERROR ("ChannelWidth " << channelWidth << " unsupported");
411 break;
412 }
413
414 //Build transmit spectrum mask
415 CreateSpectrumMaskForOfdm (c, subBands, maskBand,
416 txPowerPerBandW, nGuardBands,
417 innerSlopeWidth, minInnerBandDbr,
418 minOuterBandDbr, lowestPointDbr);
419 NormalizeSpectrumMask (c, txPowerW);
420 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation failed");
421 return c;
422}
423
425WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, WifiSpectrumBand ru)
426{
427 NS_LOG_FUNCTION (centerFrequency << channelWidth << txPowerW << guardBandwidth << ru.first << ru.second);
428 uint32_t bandBandwidth = 78125;
429 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequency, channelWidth, bandBandwidth, guardBandwidth));
430
431 //Build spectrum mask
432 Values::iterator vit = c->ValuesBegin ();
433 Bands::const_iterator bit = c->ConstBandsBegin ();
434 double txPowerPerBandW = (txPowerW / (ru.second - ru.first + 1)); //FIXME: null subcarriers
435 uint32_t numBands = c->GetSpectrumModel ()->GetNumBands ();
436 for (size_t i = 0; i < numBands; i++, vit++, bit++)
437 {
438 if (i < ru.first || i > ru.second) //outside the spectrum mask
439 {
440 *vit = 0.0;
441 }
442 else
443 {
444 *vit = (txPowerPerBandW / (bit->fh - bit->fl));
445 }
446 }
447
448 return c;
449}
450
452WifiSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t centerFrequency, uint16_t channelWidth, uint32_t bandBandwidth, double noiseFigure, uint16_t guardBandwidth)
453{
454 Ptr<SpectrumModel> model = GetSpectrumModel (centerFrequency, channelWidth, bandBandwidth, guardBandwidth);
455 return CreateNoisePowerSpectralDensity (noiseFigure, model);
456}
457
460{
461 NS_LOG_FUNCTION (noiseFigureDb << spectrumModel);
462
463 // see "LTE - From theory to practice"
464 // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
465 const double kT_dBm_Hz = -174.0; // dBm/Hz
466 double kT_W_Hz = DbmToW (kT_dBm_Hz);
467 double noiseFigureLinear = std::pow (10.0, noiseFigureDb / 10.0);
468 double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
469
470 Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (spectrumModel);
471 (*noisePsd) = noisePowerSpectralDensity;
472 NS_LOG_INFO ("NoisePowerSpectralDensity has integrated power of " << Integral (*noisePsd));
473 return noisePsd;
474}
475
477WifiSpectrumValueHelper::CreateRfFilter (uint32_t centerFrequency, uint16_t totalChannelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth, WifiSpectrumBand band)
478{
479 uint32_t startIndex = band.first;
480 uint32_t stopIndex = band.second;
481 NS_LOG_FUNCTION (centerFrequency << totalChannelWidth << bandBandwidth << guardBandwidth << startIndex << stopIndex);
482 Ptr<SpectrumValue> c = Create <SpectrumValue> (GetSpectrumModel (centerFrequency, totalChannelWidth, bandBandwidth, guardBandwidth));
483 Bands::const_iterator bit = c->ConstBandsBegin ();
484 Values::iterator vit = c->ValuesBegin ();
485 vit += startIndex;
486 bit += startIndex;
487 for (size_t i = startIndex; i <= stopIndex; i++, vit++, bit++)
488 {
489 *vit = 1;
490 }
491 NS_LOG_LOGIC ("Added subbands " << startIndex << " to " << stopIndex << " to filter");
492 return c;
493}
494
495void
496WifiSpectrumValueHelper::CreateSpectrumMaskForOfdm (Ptr<SpectrumValue> c, std::vector <WifiSpectrumBand> allocatedSubBands, WifiSpectrumBand maskBand,
497 double txPowerPerBandW, uint32_t nGuardBands, uint32_t innerSlopeWidth,
498 double minInnerBandDbr, double minOuterBandDbr, double lowestPointDbr)
499{
500 NS_LOG_FUNCTION (c << allocatedSubBands.front ().first << allocatedSubBands.back ().second << maskBand.first << maskBand.second <<
501 txPowerPerBandW << nGuardBands << innerSlopeWidth << minInnerBandDbr << minOuterBandDbr << lowestPointDbr);
502 uint32_t numSubBands = allocatedSubBands.size ();
503 uint32_t numBands = c->GetSpectrumModel ()->GetNumBands ();
504 uint32_t numMaskBands = maskBand.second - maskBand.first + 1;
505 NS_ASSERT (numSubBands && numBands && numMaskBands);
506 NS_LOG_LOGIC ("Power per band " << txPowerPerBandW << "W");
507
508 //Different power levels
509 double txPowerRefDbm = (10.0 * std::log10 (txPowerPerBandW * 1000.0));
510 double txPowerInnerBandMinDbm = txPowerRefDbm + minInnerBandDbr;
511 double txPowerMiddleBandMinDbm = txPowerRefDbm + minOuterBandDbr;
512 double txPowerOuterBandMinDbm = txPowerRefDbm + lowestPointDbr; //TODO also take into account dBm/MHz constraints
513
514 //Different widths (in number of bands)
515 uint32_t outerSlopeWidth = nGuardBands / 4; // nGuardBands is the total left+right guard band. The left/right outer part is half of the left/right guard band.
516 uint32_t middleSlopeWidth = outerSlopeWidth - (innerSlopeWidth / 2);
517 WifiSpectrumBand outerBandLeft (maskBand.first, //to handle cases where allocated channel is under WifiPhy configured channel width.
518 maskBand.first + outerSlopeWidth - 1);
519 WifiSpectrumBand middleBandLeft (outerBandLeft.second + 1,
520 outerBandLeft.second + middleSlopeWidth);
521 WifiSpectrumBand innerBandLeft (allocatedSubBands.front ().first - innerSlopeWidth,
522 allocatedSubBands.front ().first - 1); //better to place slope based on allocated subcarriers
523 WifiSpectrumBand flatJunctionLeft (middleBandLeft.second + 1,
524 innerBandLeft.first - 1); //in order to handle shift due to guard subcarriers
525 WifiSpectrumBand outerBandRight (maskBand.second - outerSlopeWidth + 1,
526 maskBand.second); //start from outer edge to be able to compute flat junction width
527 WifiSpectrumBand middleBandRight (outerBandRight.first - middleSlopeWidth,
528 outerBandRight.first - 1);
529 WifiSpectrumBand innerBandRight (allocatedSubBands.back ().second + 1,
530 allocatedSubBands.back ().second + innerSlopeWidth);
531 WifiSpectrumBand flatJunctionRight (innerBandRight.second + 1,
532 middleBandRight.first - 1);
533 NS_LOG_DEBUG ("outerBandLeft=[" << outerBandLeft.first << ";" << outerBandLeft.second << "] " <<
534 "middleBandLeft=[" << middleBandLeft.first << ";" << middleBandLeft.second << "] " <<
535 "flatJunctionLeft=[" << flatJunctionLeft.first << ";" << flatJunctionLeft.second << "] " <<
536 "innerBandLeft=[" << innerBandLeft.first << ";" << innerBandLeft.second << "] " <<
537 "subBands=[" << allocatedSubBands.front ().first << ";" << allocatedSubBands.back ().second << "] " <<
538 "innerBandRight=[" << innerBandRight.first << ";" << innerBandRight.second << "] " <<
539 "flatJunctionRight=[" << flatJunctionRight.first << ";" << flatJunctionRight.second << "] " <<
540 "middleBandRight=[" << middleBandRight.first << ";" << middleBandRight.second << "] " <<
541 "outerBandRight=[" << outerBandRight.first << ";" << outerBandRight.second << "] ");
542 NS_ASSERT (numMaskBands == ((allocatedSubBands.back ().second - allocatedSubBands.front ().first + 1) //equivalent to allocatedBand (includes notches and DC)
543 + 2 * (innerSlopeWidth + middleSlopeWidth + outerSlopeWidth)
544 + (flatJunctionLeft.second - flatJunctionLeft.first + 1) //flat junctions
545 + (flatJunctionRight.second - flatJunctionRight.first + 1)));
546
547 //Different slopes
548 double innerSlope = (-1 * minInnerBandDbr) / innerSlopeWidth;
549 double middleSlope = (-1 * (minOuterBandDbr - minInnerBandDbr)) / middleSlopeWidth;
550 double outerSlope = (txPowerMiddleBandMinDbm - txPowerOuterBandMinDbm) / outerSlopeWidth;
551
552 //Build spectrum mask
553 Values::iterator vit = c->ValuesBegin ();
554 Bands::const_iterator bit = c->ConstBandsBegin ();
555 double txPowerW = 0.0;
556 for (size_t i = 0; i < numBands; i++, vit++, bit++)
557 {
558 if (i < maskBand.first || i > maskBand.second) //outside the spectrum mask
559 {
560 txPowerW = 0.0;
561 }
562 else if (i <= outerBandLeft.second && i >= outerBandLeft.first) //better to put greater first (less computation)
563 {
564 txPowerW = DbmToW (txPowerOuterBandMinDbm + ((i - outerBandLeft.first) * outerSlope));
565 }
566 else if (i <= middleBandLeft.second && i >= middleBandLeft.first)
567 {
568 txPowerW = DbmToW (txPowerMiddleBandMinDbm + ((i - middleBandLeft.first) * middleSlope));
569 }
570 else if (i <= flatJunctionLeft.second && i >= flatJunctionLeft.first)
571 {
572 txPowerW = DbmToW (txPowerInnerBandMinDbm);
573 }
574 else if (i <= innerBandLeft.second && i >= innerBandLeft.first)
575 {
576 txPowerW = DbmToW (txPowerInnerBandMinDbm + ((i - innerBandLeft.first) * innerSlope));
577 }
578 else if (i <= allocatedSubBands.back ().second && i >= allocatedSubBands.front ().first) //roughly in allocated band
579 {
580 bool insideSubBand = false;
581 for (uint32_t j = 0; !insideSubBand && j < numSubBands; j++) //continue until inside a sub-band
582 {
583 insideSubBand = (i <= allocatedSubBands[j].second) && (i >= allocatedSubBands[j].first);
584 }
585 if (insideSubBand)
586 {
587 txPowerW = txPowerPerBandW;
588 }
589 else
590 {
591 txPowerW = DbmToW (txPowerInnerBandMinDbm);
592 }
593 }
594 else if (i <= innerBandRight.second && i >= innerBandRight.first)
595 {
596 txPowerW = DbmToW (txPowerRefDbm - ((i - innerBandRight.first + 1) * innerSlope)); // +1 so as to be symmetric with left slope
597 }
598 else if (i <= flatJunctionRight.second && i >= flatJunctionRight.first)
599 {
600 txPowerW = DbmToW (txPowerInnerBandMinDbm);
601 }
602 else if (i <= middleBandRight.second && i >= middleBandRight.first)
603 {
604 txPowerW = DbmToW (txPowerInnerBandMinDbm - ((i - middleBandRight.first + 1) * middleSlope)); // +1 so as to be symmetric with left slope
605 }
606 else if (i <= outerBandRight.second && i >= outerBandRight.first)
607 {
608 txPowerW = DbmToW (txPowerMiddleBandMinDbm - ((i - outerBandRight.first + 1) * outerSlope)); // +1 so as to be symmetric with left slope
609 }
610 else
611 {
612 NS_FATAL_ERROR ("Should have handled all cases");
613 }
614 double txPowerDbr = 10 * std::log10 (txPowerW / txPowerPerBandW);
615 NS_LOG_LOGIC (uint32_t (i) << " -> " << txPowerDbr);
616 *vit = txPowerW / (bit->fh - bit->fl);
617 }
618 NS_LOG_INFO ("Added signal power to subbands " << allocatedSubBands.front ().first << "-" << allocatedSubBands.back ().second);
619}
620
621void
623{
624 NS_LOG_FUNCTION (c << txPowerW);
625 //Normalize power so that total signal power equals transmit power
626 double currentTxPowerW = Integral (*c);
627 double normalizationRatio = currentTxPowerW / txPowerW;
628 NS_LOG_LOGIC ("Current power: " << currentTxPowerW << "W vs expected power: " << txPowerW << "W" <<
629 " -> ratio (C/E) = " << normalizationRatio);
630 Values::iterator vit = c->ValuesBegin ();
631 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++)
632 {
633 *vit = (*vit) / normalizationRatio;
634 }
635}
636
637double
639{
640 return std::pow (10.0, 0.1 * (dBm - 30.0));
641}
642
643double
645{
646 double powerWattPerHertz = 0.0;
647 auto valueIt = psd->ConstValuesBegin() + band.first;
648 auto end = psd->ConstValuesBegin() + band.second;
649 auto bandIt = psd->ConstBandsBegin() + band.first;
650 while (valueIt <= end)
651 {
652 powerWattPerHertz += *valueIt;
653 ++valueIt;
654 }
655 return powerWattPerHertz * (bandIt->fh - bandIt->fl);
656}
657
659
661{
662}
663
665{
666}
667
672{
673public:
675 {
676 Bands bands;
677 for (int i = -4; i < 13 + 7; i++)
678 {
679 BandInfo bi;
680 bi.fl = 2407.0e6 + i * 5.0e6;
681 bi.fh = 2407.0e6 + (i + 1) * 5.0e6;
682 bi.fc = (bi.fl + bi.fh) / 2;
683 bands.push_back (bi);
684 }
685 g_WifiSpectrumModel5Mhz = Create<SpectrumModel> (bands);
686 }
688
689
690
691Ptr<SpectrumValue>
693{
694 Ptr<SpectrumValue> c = Create <SpectrumValue> (g_WifiSpectrumModel5Mhz);
695 (*c) = v;
696 return c;
697}
698
699
702{
703 Ptr<SpectrumValue> txPsd = Create <SpectrumValue> (g_WifiSpectrumModel5Mhz);
704
705 // since the spectrum model has a resolution of 5 MHz, we model
706 // the transmitted signal with a constant density over a 20MHz
707 // bandwidth centered on the center frequency of the channel. The
708 // transmission power outside the transmission power density is
709 // calculated considering the transmit spectrum mask, see IEEE
710 // Std. 802.11-2007, Annex I
711
712 double txPowerDensity = txPower / 20e6;
713
714 NS_ASSERT (channel >= 1);
715 NS_ASSERT (channel <= 13);
716
717 (*txPsd)[channel - 1] = txPowerDensity * 1e-4; // -40dB
718 (*txPsd)[channel] = txPowerDensity * 1e-4; // -40dB
719 (*txPsd)[channel + 1] = txPowerDensity * 0.0015849; // -28dB
720 (*txPsd)[channel + 2] = txPowerDensity * 0.0015849; // -28dB
721 (*txPsd)[channel + 3] = txPowerDensity;
722 (*txPsd)[channel + 4] = txPowerDensity;
723 (*txPsd)[channel + 5] = txPowerDensity;
724 (*txPsd)[channel + 6] = txPowerDensity;
725 (*txPsd)[channel + 7] = txPowerDensity * 0.0015849; // -28dB
726 (*txPsd)[channel + 8] = txPowerDensity * 0.0015849; // -28dB
727 (*txPsd)[channel + 9] = txPowerDensity * 1e-4; // -40dB
728 (*txPsd)[channel + 10] = txPowerDensity * 1e-4; // -40dB
729
730 return txPsd;
731}
732
735{
736 Ptr<SpectrumValue> rf = Create <SpectrumValue> (g_WifiSpectrumModel5Mhz);
737
738 NS_ASSERT (channel >= 1);
739 NS_ASSERT (channel <= 13);
740
741 (*rf)[channel + 3] = 1;
742 (*rf)[channel + 4] = 1;
743 (*rf)[channel + 5] = 1;
744 (*rf)[channel + 6] = 1;
745
746 return rf;
747}
748
749} // namespace ns3
double f(double x, void *params)
Definition: 80211b.c:70
size_t GetNumBands() const
SpectrumModelUid_t GetUid() const
Values::const_iterator ConstValuesBegin() const
Values::iterator ValuesBegin()
Bands::const_iterator ConstBandsBegin() const
Ptr< const SpectrumModel > GetSpectrumModel() const
Static class to initialize the values for the 2.4 GHz Wi-Fi spectrum model.
virtual Ptr< SpectrumValue > CreateConstant(double psd)
Creates a SpectrumValue instance with a constant value for all frequencies.
virtual Ptr< SpectrumValue > CreateRfFilter(uint8_t channel)
Creates a SpectrumValue instance which represents the frequency response of the RF filter which is us...
virtual Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double txPower, uint8_t channel)
Creates a SpectrumValue instance that represents the TX Power Spectral Density of a wifi device corre...
static Ptr< SpectrumValue > CreateHtOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, double minInnerBandDbr=-20, double minOuterbandDbr=-28, double lowestPointDbr=-40)
Create a transmit power spectral density corresponding to OFDM High Throughput (HT) (802....
static Ptr< SpectrumValue > CreateOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, double minInnerBandDbr=-20, double minOuterbandDbr=-28, double lowestPointDbr=-40)
Create a transmit power spectral density corresponding to OFDM (802.11a/g).
static Ptr< SpectrumValue > CreateDsssTxPowerSpectralDensity(uint32_t centerFrequency, double txPowerW, uint16_t guardBandwidth)
Create a transmit power spectral density corresponding to DSSS.
static Ptr< SpectrumModel > GetSpectrumModel(uint32_t centerFrequency, uint16_t channelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth)
Return a SpectrumModel instance corresponding to the center frequency and channel width.
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, uint32_t bandBandwidth, double noiseFigure, uint16_t guardBandwidth)
Create a power spectral density corresponding to the noise.
static Ptr< SpectrumValue > CreateHeMuOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, WifiSpectrumBand ru)
Create a transmit power spectral density corresponding to the OFDMA part of HE TB PPDUs for a given R...
static double DbmToW(double dbm)
Convert from dBm to Watts.
static void NormalizeSpectrumMask(Ptr< SpectrumValue > c, double txPowerW)
Normalize the transmit spectrum mask generated by CreateSpectrumMaskForOfdm so that the total transmi...
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, double minInnerBandDbr=-20, double minOuterbandDbr=-28, double lowestPointDbr=-40)
Create a transmit power spectral density corresponding to OFDM High Efficiency (HE) (802....
static void CreateSpectrumMaskForOfdm(Ptr< SpectrumValue > c, std::vector< WifiSpectrumBand > allocatedSubBands, WifiSpectrumBand maskBand, double txPowerPerBandW, uint32_t nGuardBands, uint32_t innerSlopeWidth, double minInnerBandDbr, double minOuterbandDbr, double lowestPointDbr)
Create a transmit power spectral density corresponding to OFDM transmit spectrum mask requirements fo...
static double GetBandPowerW(Ptr< SpectrumValue > psd, const WifiSpectrumBand &band)
Calculate the power of the specified band composed of uniformly-sized sub-bands.
static Ptr< SpectrumValue > CreateRfFilter(uint32_t centerFrequency, uint16_t totalChannelWidth, uint32_t bandBandwidth, uint16_t guardBandwidth, WifiSpectrumBand band)
Create a spectral density corresponding to the RF filter.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static Ptr< SpectrumModel > g_WifiSpectrumModel5Mhz
static initializer for the class
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
double Integral(const SpectrumValue &arg)
std::vector< BandInfo > Bands
Container of BandInfo.
static class ns3::WifiSpectrumModel5MhzInitializer g_WifiSpectrumModel5MhzInitializerInstance
initialization instance for WifiSpectrumModel5Mhz
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:176
static std::map< WifiSpectrumModelId, Ptr< SpectrumModel > > g_wifiSpectrumModelMap
static initializer for the class
channel
Definition: third.py:92
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
Wifi Spectrum Model structure.
uint32_t m_centerFrequency
center frequency (in MHz)
uint16_t m_guardBandwidth
guard band width (in MHz)
double m_bandBandwidth
width of each band (in Hz)
uint16_t m_channelWidth
channel width (in MHz)
WifiSpectrumModelId(uint32_t f, uint16_t w, double b, uint16_t g)
Constructor.