OLD | NEW |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2009 CTTC | 3 * Copyright (c) 2009 CTTC |
4 * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari | 4 * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari |
| 5 * Copyright (c) 2017 Orange Labs |
5 * | 6 * |
6 * This program is free software; you can redistribute it and/or modify | 7 * This program is free software; you can redistribute it and/or modify |
7 * it under the terms of the GNU General Public License version 2 as | 8 * it under the terms of the GNU General Public License version 2 as |
8 * published by the Free Software Foundation; | 9 * published by the Free Software Foundation; |
9 * | 10 * |
10 * This program is distributed in the hope that it will be useful, | 11 * This program is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 * GNU General Public License for more details. | 14 * GNU General Public License for more details. |
14 * | 15 * |
15 * You should have received a copy of the GNU General Public License | 16 * You should have received a copy of the GNU General Public License |
16 * along with this program; if not, write to the Free Software | 17 * along with this program; if not, write to the Free Software |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 * | 19 * |
19 * Author: Nicola Baldo <nbaldo@cttc.es> | 20 * Authors: Nicola Baldo <nbaldo@cttc.es> |
20 * Giuseppe Piro <g.piro@poliba.it> | 21 * Giuseppe Piro <g.piro@poliba.it> |
| 22 * Rediet <getachew.redieteab@orange.com> |
21 */ | 23 */ |
22 | 24 |
23 #include <map> | 25 #include <map> |
24 #include <cmath> | 26 #include <cmath> |
25 #include "wifi-spectrum-value-helper.h" | 27 #include "wifi-spectrum-value-helper.h" |
26 #include "ns3/log.h" | 28 #include "ns3/log.h" |
27 #include "ns3/fatal-error.h" | 29 #include "ns3/fatal-error.h" |
28 #include "ns3/assert.h" | 30 #include "ns3/assert.h" |
29 | 31 |
30 namespace ns3 { | 32 namespace ns3 { |
31 | 33 |
32 NS_LOG_COMPONENT_DEFINE ("WifiSpectrumValueHelper"); | 34 NS_LOG_COMPONENT_DEFINE ("WifiSpectrumValueHelper"); |
33 | 35 |
34 ///< Wifi Spectrum Model structure | 36 ///< Wifi Spectrum Model structure |
35 struct WifiSpectrumModelId | 37 struct WifiSpectrumModelId |
36 { | 38 { |
37 /** | 39 /** |
38 * Constructor | 40 * Constructor |
39 * \param f the frequency in Mhz | 41 * \param f the frequency (in MHz) |
40 * \param w the channel width in Mhz | 42 * \param w the channel width (in MHz) |
| 43 * \param b the width of each band (in Hz) |
| 44 * \param g the guard band width (in MHz) |
41 */· | 45 */· |
42 WifiSpectrumModelId (uint32_t f, uint8_t w); | 46 WifiSpectrumModelId (uint32_t f, uint8_t w, double b, uint8_t g); |
43 uint32_t m_centerFrequency; ///< center frequency | 47 uint32_t m_centerFrequency; ///< center frequency (in MHz) |
44 uint8_t m_channelWidth; ///< channel width | 48 uint8_t m_channelWidth; ///< channel width (in MHz) |
| 49 double m_bandBandwidth; ///< width of each band (in Hz) |
| 50 uint8_t m_guardBandwidth; ///< guard band width (in MHz) |
45 }; | 51 }; |
46 | 52 |
47 WifiSpectrumModelId::WifiSpectrumModelId (uint32_t f, uint8_t w) | 53 WifiSpectrumModelId::WifiSpectrumModelId (uint32_t f, uint8_t w, double b, uint8
_t g) |
48 : m_centerFrequency (f), | 54 : m_centerFrequency (f), |
49 m_channelWidth (w) | 55 m_channelWidth (w), |
| 56 m_bandBandwidth (b), |
| 57 m_guardBandwidth (g) |
50 { | 58 { |
51 NS_LOG_FUNCTION (this << f << (uint16_t)w); | 59 NS_LOG_FUNCTION (this << f << (uint16_t)w << b << (uint16_t)g); |
52 } | 60 } |
53 | 61 |
54 /** | 62 /** |
55 * Less than operator | 63 * Less than operator |
56 * \param a the first wifi spectrum to compare | 64 * \param a the first wifi spectrum to compare |
57 * \param b the second wifi spectrum to compare | 65 * \param b the second wifi spectrum to compare |
58 * \returns true if the first spectrum is less than the second spectrum | 66 * \returns true if the first spectrum is less than the second spectrum |
59 */· | 67 */· |
60 bool | 68 bool |
61 operator < (const WifiSpectrumModelId& a, const WifiSpectrumModelId& b) | 69 operator < (const WifiSpectrumModelId& a, const WifiSpectrumModelId& b) |
62 { | 70 { |
63 return ( (a.m_centerFrequency < b.m_centerFrequency) || ( (a.m_centerFrequency
== b.m_centerFrequency) && (a.m_channelWidth < b.m_channelWidth))); | 71 return ( (a.m_centerFrequency < b.m_centerFrequency) |
| 72 || ((a.m_centerFrequency == b.m_centerFrequency) && |
| 73 (a.m_channelWidth < b.m_channelWidth)) |
| 74 || ((a.m_centerFrequency == b.m_centerFrequency) && |
| 75 (a.m_channelWidth == b.m_channelWidth) && |
| 76 (a.m_bandBandwidth < b.m_bandBandwidth)) // to cover coexistence o
f 11ax with legacy case |
| 77 || ((a.m_centerFrequency == b.m_centerFrequency) && |
| 78 (a.m_channelWidth == b.m_channelWidth) && |
| 79 (a.m_bandBandwidth == b.m_bandBandwidth) && |
| 80 (a.m_guardBandwidth < b.m_guardBandwidth))); // to cover 2.4 GHz c
ase, where DSSS coexists with OFDM |
64 } | 81 } |
65 | 82 |
66 static std::map<WifiSpectrumModelId, Ptr<SpectrumModel> > g_wifiSpectrumModelMap
; ///< static initializer for the class | 83 static std::map<WifiSpectrumModelId, Ptr<SpectrumModel> > g_wifiSpectrumModelMap
; ///< static initializer for the class |
67 | 84 |
68 Ptr<SpectrumModel> | 85 Ptr<SpectrumModel> |
69 WifiSpectrumValueHelper::GetSpectrumModel (uint32_t centerFrequency, uint8_t cha
nnelWidth, double bandBandwidth, uint8_t guardBandwidth) | 86 WifiSpectrumValueHelper::GetSpectrumModel (uint32_t centerFrequency, uint8_t cha
nnelWidth, double bandBandwidth, uint8_t guardBandwidth) |
70 { | 87 { |
71 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << bandBandwidth <<
(uint16_t)guardBandwidth); | 88 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << bandBandwidth <<
(uint16_t)guardBandwidth); |
72 Ptr<SpectrumModel> ret; | 89 Ptr<SpectrumModel> ret; |
73 WifiSpectrumModelId key (centerFrequency, channelWidth); | 90 WifiSpectrumModelId key (centerFrequency, channelWidth, bandBandwidth, guardBa
ndwidth); |
74 std::map<WifiSpectrumModelId, Ptr<SpectrumModel> >::iterator it = g_wifiSpectr
umModelMap.find (key); | 91 std::map<WifiSpectrumModelId, Ptr<SpectrumModel> >::iterator it = g_wifiSpectr
umModelMap.find (key); |
75 if (it != g_wifiSpectrumModelMap.end ()) | 92 if (it != g_wifiSpectrumModelMap.end ()) |
76 { | 93 { |
77 ret = it->second; | 94 ret = it->second; |
78 } | 95 } |
79 else | 96 else |
80 { | 97 { |
81 Bands bands; | 98 Bands bands; |
82 double centerFrequencyHz = centerFrequency * 1e6; | 99 double centerFrequencyHz = centerFrequency * 1e6; |
83 double bandwidth = (channelWidth + (2 * guardBandwidth)) * 1e6; | 100 double bandwidth = (channelWidth + (2 * guardBandwidth)) * 1e6; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 | 158 |
142 Ptr<SpectrumValue> | 159 Ptr<SpectrumValue> |
143 WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity (uint32_t centerFreque
ncy, uint8_t channelWidth, double txPowerW, uint8_t guardBandwidth) | 160 WifiSpectrumValueHelper::CreateOfdmTxPowerSpectralDensity (uint32_t centerFreque
ncy, uint8_t channelWidth, double txPowerW, uint8_t guardBandwidth) |
144 { | 161 { |
145 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << txPowerW << (uin
t16_t)guardBandwidth); | 162 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << txPowerW << (uin
t16_t)guardBandwidth); |
146 double bandBandwidth = 312500; | 163 double bandBandwidth = 312500; |
147 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequenc
y, channelWidth, bandBandwidth, guardBandwidth)); | 164 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequenc
y, channelWidth, bandBandwidth, guardBandwidth)); |
148 uint32_t nGuardBands = static_cast<uint32_t>(((2 * guardBandwidth * 1e6) / ban
dBandwidth) + 0.5); | 165 uint32_t nGuardBands = static_cast<uint32_t>(((2 * guardBandwidth * 1e6) / ban
dBandwidth) + 0.5); |
149 uint32_t nAllocatedBands = static_cast<uint32_t>(((channelWidth * 1e6) / bandB
andwidth) + 0.5); | 166 uint32_t nAllocatedBands = static_cast<uint32_t>(((channelWidth * 1e6) / bandB
andwidth) + 0.5); |
150 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nG
uardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumB
ands ()); | 167 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nG
uardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumB
ands ()); |
151 double txPowerPerBand = 0; | 168 double txPowerPerBandW = 0.0; |
152 uint32_t start1 = 0; | 169 uint32_t start1 = 0; |
153 uint32_t stop1 = 0; | 170 uint32_t stop1 = 0; |
154 uint32_t start2 = 0; | 171 uint32_t start2 = 0; |
155 uint32_t stop2 = 0; | 172 uint32_t stop2 = 0; |
| 173 uint32_t innerSlopeWidth = 0; |
156 switch (channelWidth) | 174 switch (channelWidth) |
157 { | 175 { |
158 case 20: | 176 case 20: |
159 default: | |
160 // 52 subcarriers (48 data + 4 pilot) | 177 // 52 subcarriers (48 data + 4 pilot) |
161 // skip guard band and 6 subbands, then place power in 26 subbands, then | 178 // skip guard band and 6 subbands, then place power in 26 subbands, then |
162 // skip the center subband, then place power in 26 subbands, then skip | 179 // skip the center subband, then place power in 26 subbands, then skip |
163 // the final 6 subbands and the guard band. | 180 // the final 6 subbands and the guard band. |
164 txPowerPerBand = txPowerW / 52; | 181 txPowerPerBandW = txPowerW / 52; |
165 start1 = (nGuardBands / 2) + 6; | 182 start1 = (nGuardBands / 2) + 6; |
166 stop1 = start1 + 26 - 1; | 183 stop1 = start1 + 26 - 1; |
167 start2 = stop1 + 2; | 184 start2 = stop1 + 2; |
168 stop2 = start2 + 26 - 1; | 185 stop2 = start2 + 26 - 1; |
| 186 innerSlopeWidth = static_cast<uint32_t>((2e6 / bandBandwidth) + 0.5); // [
-11;-9] & [9;11] |
169 break; | 187 break; |
170 case 10: | 188 case 10: |
171 // 28 subcarriers (24 data + 4 pilot) | 189 // 28 subcarriers (24 data + 4 pilot) |
172 // skip guard band and 2 subbands, then place power in 14 subbands, then | 190 // skip guard band and 2 subbands, then place power in 14 subbands, then |
173 // skip the center subband, then place power in 14 subbands, then skip | 191 // skip the center subband, then place power in 14 subbands, then skip |
174 // the final 2 subbands and the guard band. | 192 // the final 2 subbands and the guard band. |
175 txPowerPerBand = txPowerW / 28; | 193 txPowerPerBandW = txPowerW / 28; |
176 start1 = (nGuardBands / 2) + 2; | 194 start1 = (nGuardBands / 2) + 2; |
177 stop1 = start1 + 14 - 1; | 195 stop1 = start1 + 14 - 1; |
178 start2 = stop1 + 2; | 196 start2 = stop1 + 2; |
179 stop2 = start2 + 14 - 1; | 197 stop2 = start2 + 14 - 1; |
| 198 innerSlopeWidth = static_cast<uint32_t>((1e6 / bandBandwidth) + 0.5); // [
-5.5;-4.5] & [4.5;5.5] |
180 break; | 199 break; |
181 case 5: | 200 case 5: |
182 // 16 subcarriers (12 data + 4 pilot) | 201 // 16 subcarriers (12 data + 4 pilot) |
183 // skip guard band and 2 subbands, then place power in 8 subbands, then | 202 // skip guard band and 2 subbands, then place power in 8 subbands, then |
184 // skip the center subband, then place power in 8 subbands, then skip | 203 // skip the center subband, then place power in 8 subbands, then skip |
185 // the final 2 subbands and the guard. | 204 // the final 2 subbands and the guard. |
186 txPowerPerBand = txPowerW / 16; | 205 txPowerPerBandW = txPowerW / 16; |
187 start1 = (nGuardBands / 2) + 2; | 206 start1 = (nGuardBands / 2) + 2; |
188 stop1 = start1 + 8 - 1; | 207 stop1 = start1 + 8 - 1; |
189 start2 = stop1 + 2; | 208 start2 = stop1 + 2; |
190 stop2 = start2 + 8 - 1; | 209 stop2 = start2 + 8 - 1; |
| 210 innerSlopeWidth = static_cast<uint32_t>((5e5 / bandBandwidth) + 0.5); // [
-2.75;-2.5] & [2.5;2.75] |
191 break; | 211 break; |
| 212 default: |
| 213 NS_FATAL_ERROR ("Channel width should be correctly set."); |
| 214 return 0; |
192 } | 215 } |
193 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 216 |
194 Values::iterator vit = c->ValuesBegin (); | 217 //Build transmit spectrum mask |
195 Bands::const_iterator bit = c->ConstBandsBegin (); | 218 std::vector <StartStop> subBands; |
196 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++, bit
++) | 219 subBands.push_back (std::make_pair (start1, stop1)); |
197 { | 220 subBands.push_back (std::make_pair (start2, stop2)); |
198 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2)) | 221 StartStop maskBand (0, nAllocatedBands + nGuardBands); |
199 { | 222 CreateSpectrumMaskForOfdm (c, subBands, maskBand, |
200 *vit = txPowerPerBand / (bit->fh - bit->fl); | 223 txPowerPerBandW, nGuardBands, |
201 } | 224 innerSlopeWidth, -40.0); // -40 dBr for the outmost
points of the standard defined mask for 11a, 11g and downclocked versions of 11
a for 11p |
202 else | 225 NormalizeSpectrumMask (c, txPowerW); |
203 { | |
204 *vit = 0; | |
205 } | |
206 } | |
207 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1 << "
and " << start2 << "-" << stop2); | |
208 NS_LOG_DEBUG ("Integrated power " << Integral (*c)); | |
209 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation f
ailed"); | 226 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation f
ailed"); |
210 return c; | 227 return c; |
211 } | 228 } |
212 | 229 |
213 Ptr<SpectrumValue> | 230 Ptr<SpectrumValue> |
214 WifiSpectrumValueHelper::CreateHtOfdmTxPowerSpectralDensity (uint32_t centerFreq
uency, uint8_t channelWidth, double txPowerW, uint8_t guardBandwidth) | 231 WifiSpectrumValueHelper::CreateHtOfdmTxPowerSpectralDensity (uint32_t centerFreq
uency, uint8_t channelWidth, double txPowerW, uint8_t guardBandwidth) |
215 { | 232 { |
216 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << txPowerW << (uin
t16_t)guardBandwidth); | 233 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << txPowerW << (uin
t16_t)guardBandwidth); |
217 double bandBandwidth = 312500; | 234 double bandBandwidth = 312500; |
218 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequenc
y, channelWidth, bandBandwidth, guardBandwidth)); | 235 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequenc
y, channelWidth, bandBandwidth, guardBandwidth)); |
219 Values::iterator vit = c->ValuesBegin (); | |
220 Bands::const_iterator bit = c->ConstBandsBegin (); | |
221 uint32_t nGuardBands = static_cast<uint32_t>(((2 * guardBandwidth * 1e6) / ban
dBandwidth) + 0.5); | 236 uint32_t nGuardBands = static_cast<uint32_t>(((2 * guardBandwidth * 1e6) / ban
dBandwidth) + 0.5); |
222 uint32_t nAllocatedBands = static_cast<uint32_t>(((channelWidth * 1e6) / bandB
andwidth) + 0.5); | 237 uint32_t nAllocatedBands = static_cast<uint32_t>(((channelWidth * 1e6) / bandB
andwidth) + 0.5); |
223 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nG
uardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumB
ands ()); | 238 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nG
uardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumB
ands ()); |
224 double txPowerPerBand; | 239 double txPowerPerBandW = 0.0; |
225 // skip the guard band and 4 subbands, then place power in 28 subbands, then | 240 // 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 | 241 // skip the center subband, then place power in 28 subbands, then skip |
227 // the final 4 subbands and the guard band. | 242 // the final 4 subbands and the guard band. |
228 // Repeat for each 20 MHz band. | 243 // Repeat for each 20 MHz band. |
229 uint32_t start1 = (nGuardBands / 2) + 4; | 244 uint32_t start1 = (nGuardBands / 2) + 4; |
230 uint32_t stop1 = start1 + 28 - 1; | 245 uint32_t stop1 = start1 + 28 - 1; |
231 uint32_t start2 = stop1 + 2; | 246 uint32_t start2 = stop1 + 2; |
232 uint32_t stop2 = start2 + 28 - 1; | 247 uint32_t stop2 = start2 + 28 - 1; |
233 uint32_t start3 = stop2 + (2 * 4); | 248 uint32_t start3 = stop2 + (2 * 4); |
234 uint32_t stop3 = start3 + 28 - 1; | 249 uint32_t stop3 = start3 + 28 - 1; |
(...skipping 16 matching lines...) Expand all Loading... |
251 uint32_t start12 = stop11 + 2; | 266 uint32_t start12 = stop11 + 2; |
252 uint32_t stop12 = start12 + 28 - 1; | 267 uint32_t stop12 = start12 + 28 - 1; |
253 uint32_t start13 = stop12 + (2 * 4); | 268 uint32_t start13 = stop12 + (2 * 4); |
254 uint32_t stop13 = start13 + 28 - 1; | 269 uint32_t stop13 = start13 + 28 - 1; |
255 uint32_t start14 = stop13 + 2; | 270 uint32_t start14 = stop13 + 2; |
256 uint32_t stop14 = start14 + 28 - 1; | 271 uint32_t stop14 = start14 + 28 - 1; |
257 uint32_t start15 = stop14 + (2 * 4); | 272 uint32_t start15 = stop14 + (2 * 4); |
258 uint32_t stop15 = start15 + 28 - 1; | 273 uint32_t stop15 = start15 + 28 - 1; |
259 uint32_t start16 = stop15 + 2; | 274 uint32_t start16 = stop15 + 2; |
260 uint32_t stop16 = start16 + 28 - 1; | 275 uint32_t stop16 = start16 + 28 - 1; |
| 276 //Prepare spectrum mask specific variables |
| 277 uint32_t innerSlopeWidth = static_cast<uint32_t>((2e6 / bandBandwidth) + 0.5);
//size in number of subcarriers of the 0dBr<->20dBr slope (2MHz for HT/VHT) |
| 278 double lowestPointDbr = (centerFrequency >= 5000) ? |
| 279 -40.0 : //if 5 GHz band |
| 280 -45.0; //if 2.4 GHz band |
| 281 std::vector <StartStop> subBands; //list of data/pilot-containing subBands (se
nt at 0dBr) |
| 282 StartStop maskBand (0, nAllocatedBands + nGuardBands); |
261 switch (channelWidth) | 283 switch (channelWidth) |
262 { | 284 { |
263 case 20: | 285 case 20: |
264 // 56 subcarriers (52 data + 4 pilot) | 286 // 56 subcarriers (52 data + 4 pilot) |
265 txPowerPerBand = txPowerW / 56; | 287 txPowerPerBandW = txPowerW / 56; |
266 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 288 subBands.push_back (std::make_pair (start1, stop1)); |
267 start1 = (nGuardBands / 2) + 4; | 289 subBands.push_back (std::make_pair (start2, stop2)); |
268 stop1 = start1 + 28 - 1; | |
269 start2 = stop1 + 2; | |
270 stop2 = start2 + 28 - 1; | |
271 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | |
272 { | |
273 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2)) | |
274 { | |
275 *vit = txPowerPerBand / (bit->fh - bit->fl); | |
276 } | |
277 else | |
278 { | |
279 *vit = 0; | |
280 } | |
281 } | |
282 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
283 " and " << start2 << "-" << stop2); | |
284 break; | 290 break; |
285 case 40: | 291 case 40: |
286 // 112 subcarriers (104 data + 8 pilot)· | 292 // 112 subcarriers (104 data + 8 pilot)· |
287 // possible alternative: 114 subcarriers (108 data + 6 pilot) | 293 // possible alternative: 114 subcarriers (108 data + 6 pilot) |
288 txPowerPerBand = txPowerW / 112; | 294 txPowerPerBandW = txPowerW / 112; |
289 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 295 subBands.push_back (std::make_pair (start1, stop1)); |
290 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | 296 subBands.push_back (std::make_pair (start2, stop2)); |
291 { | 297 subBands.push_back (std::make_pair (start3, stop3)); |
292 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2) || | 298 subBands.push_back (std::make_pair (start4, stop4)); |
293 (i >= start3 && i <= stop3) || (i >= start4 && i <= stop4)) | |
294 { | |
295 *vit = txPowerPerBand / (bit->fh - bit->fl); | |
296 } | |
297 else | |
298 { | |
299 *vit = 0; | |
300 } | |
301 } | |
302 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
303 ", " << start2 << "-" << stop2 << | |
304 ", " << start3 << "-" << stop3 << | |
305 ", " << start4 << "-" << stop4); | |
306 break; | 299 break; |
307 case 80: | 300 case 80: |
308 // 224 subcarriers (208 data + 16 pilot)· | 301 // 224 subcarriers (208 data + 16 pilot)· |
309 // possible alternative: 242 subcarriers (234 data + 8 pilot) | 302 // possible alternative: 242 subcarriers (234 data + 8 pilot) |
310 txPowerPerBand = txPowerW / 224; | 303 txPowerPerBandW = txPowerW / 224; |
311 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 304 NS_ASSERT (lowestPointDbr == -40.0); |
312 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | 305 subBands.push_back (std::make_pair (start1, stop1)); |
313 { | 306 subBands.push_back (std::make_pair (start2, stop2)); |
314 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2) || | 307 subBands.push_back (std::make_pair (start3, stop3)); |
315 (i >= start3 && i <= stop3) || (i >= start4 && i <= stop4) || | 308 subBands.push_back (std::make_pair (start4, stop4)); |
316 (i >= start5 && i <= stop5) || (i >= start6 && i <= stop6) || | 309 subBands.push_back (std::make_pair (start5, stop5)); |
317 (i >= start7 && i <= stop7) || (i >= start8 && i <= stop8)) | 310 subBands.push_back (std::make_pair (start6, stop6)); |
318 { | 311 subBands.push_back (std::make_pair (start7, stop7)); |
319 *vit = txPowerPerBand / (bit->fh - bit->fl); | 312 subBands.push_back (std::make_pair (start8, stop8)); |
320 } | |
321 else | |
322 { | |
323 *vit = 0; | |
324 } | |
325 } | |
326 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
327 ", " << start2 << "-" << stop2 << | |
328 ", " << start3 << "-" << stop3 << | |
329 ", " << start4 << "-" << stop4 << | |
330 ", " << start5 << "-" << stop5 << | |
331 ", " << start6 << "-" << stop6 << | |
332 ", " << start7 << "-" << stop7 << | |
333 ", " << start8 << "-" << stop8); | |
334 break; | 313 break; |
335 case 160: | 314 case 160: |
336 // 448 subcarriers (416 data + 32 pilot) | 315 // 448 subcarriers (416 data + 32 pilot) |
337 // possible alternative: 484 subcarriers (468 data + 16 pilot) | 316 // possible alternative: 484 subcarriers (468 data + 16 pilot) |
338 txPowerPerBand = txPowerW / 448; | 317 txPowerPerBandW = txPowerW / 448; |
339 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 318 NS_ASSERT (lowestPointDbr == -40.0); |
340 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | 319 subBands.push_back (std::make_pair (start1, stop1)); |
341 { | 320 subBands.push_back (std::make_pair (start2, stop2)); |
342 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2) || | 321 subBands.push_back (std::make_pair (start3, stop3)); |
343 (i >= start3 && i <= stop3) || (i >= start4 && i <= stop4) || | 322 subBands.push_back (std::make_pair (start4, stop4)); |
344 (i >= start5 && i <= stop5) || (i >= start6 && i <= stop6) || | 323 subBands.push_back (std::make_pair (start5, stop5)); |
345 (i >= start7 && i <= stop7) || (i >= start8 && i <= stop8) || | 324 subBands.push_back (std::make_pair (start6, stop6)); |
346 (i >= start9 && i <= stop9) || (i >= start10 && i <= stop10) || | 325 subBands.push_back (std::make_pair (start7, stop7)); |
347 (i >= start11 && i <= stop11) || (i >= start12 && i <= stop12) || | 326 subBands.push_back (std::make_pair (start8, stop8)); |
348 (i >= start13 && i <= stop13) || (i >= start14 && i <= stop14) || | 327 subBands.push_back (std::make_pair (start9, stop9)); |
349 (i >= start15 && i <= stop15) || (i >= start16 && i <= stop16)) | 328 subBands.push_back (std::make_pair (start10, stop10)); |
350 { | 329 subBands.push_back (std::make_pair (start11, stop11)); |
351 *vit = txPowerPerBand / (bit->fh - bit->fl); | 330 subBands.push_back (std::make_pair (start12, stop12)); |
352 } | 331 subBands.push_back (std::make_pair (start13, stop13)); |
353 else | 332 subBands.push_back (std::make_pair (start14, stop14)); |
354 { | 333 subBands.push_back (std::make_pair (start15, stop15)); |
355 *vit = 0; | 334 subBands.push_back (std::make_pair (start16, stop16)); |
356 } | |
357 } | |
358 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
359 ", " << start2 << "-" << stop2 << | |
360 ", " << start3 << "-" << stop3 << | |
361 ", " << start4 << "-" << stop4 << | |
362 ", " << start5 << "-" << stop5 << | |
363 ", " << start6 << "-" << stop6 << | |
364 ", " << start7 << "-" << stop7 << | |
365 ", " << start8 << "-" << stop8 << | |
366 ", " << start9 << "-" << stop9 << | |
367 ", " << start10 << "-" << stop10 << | |
368 ", " << start11 << "-" << stop11 << | |
369 ", " << start12 << "-" << stop12 << | |
370 ", " << start13 << "-" << stop13 << | |
371 ", " << start14 << "-" << stop14 << | |
372 ", " << start15 << "-" << stop15 << | |
373 ", " << start16 << "-" << stop16); | |
374 break; | 335 break; |
375 } | 336 } |
376 NS_LOG_DEBUG ("Integrated power " << Integral (*c)); | 337 |
| 338 //Build transmit spectrum mask |
| 339 CreateSpectrumMaskForOfdm (c, subBands, maskBand, |
| 340 txPowerPerBandW, nGuardBands, |
| 341 innerSlopeWidth, lowestPointDbr); |
| 342 NormalizeSpectrumMask (c, txPowerW); |
377 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation f
ailed"); | 343 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation f
ailed"); |
378 return c; | 344 return c; |
379 } | 345 } |
380 | 346 |
381 Ptr<SpectrumValue> | 347 Ptr<SpectrumValue> |
382 WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (uint32_t centerFreq
uency, uint8_t channelWidth, double txPowerW, uint8_t guardBandwidth) | 348 WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (uint32_t centerFreq
uency, uint8_t channelWidth, double txPowerW, uint8_t guardBandwidth) |
383 { | 349 { |
384 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << txPowerW << (uin
t16_t)guardBandwidth); | 350 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << txPowerW << (uin
t16_t)guardBandwidth); |
385 double bandBandwidth = 78125; | 351 double bandBandwidth = 78125; |
386 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequenc
y, channelWidth, bandBandwidth, guardBandwidth)); | 352 Ptr<SpectrumValue> c = Create<SpectrumValue> (GetSpectrumModel (centerFrequenc
y, channelWidth, bandBandwidth, guardBandwidth)); |
387 Values::iterator vit = c->ValuesBegin (); | |
388 Bands::const_iterator bit = c->ConstBandsBegin (); | |
389 uint32_t nGuardBands = static_cast<uint32_t>(((2 * guardBandwidth * 1e6) / ban
dBandwidth) + 0.5); | 353 uint32_t nGuardBands = static_cast<uint32_t>(((2 * guardBandwidth * 1e6) / ban
dBandwidth) + 0.5); |
390 uint32_t nAllocatedBands = static_cast<uint32_t>(((channelWidth * 1e6) / bandB
andwidth) + 0.5); | 354 uint32_t nAllocatedBands = static_cast<uint32_t>(((channelWidth * 1e6) / bandB
andwidth) + 0.5); |
391 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nG
uardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumB
ands ()); | 355 NS_ASSERT_MSG (c->GetSpectrumModel ()->GetNumBands () == (nAllocatedBands + nG
uardBands + 1), "Unexpected number of bands " << c->GetSpectrumModel ()->GetNumB
ands ()); |
392 double txPowerPerBand; | 356 double txPowerPerBandW = 0.0; |
393 uint32_t start1; | 357 uint32_t start1; |
394 uint32_t stop1; | 358 uint32_t stop1; |
395 uint32_t start2; | 359 uint32_t start2; |
396 uint32_t stop2; | 360 uint32_t stop2; |
397 uint32_t start3; | 361 uint32_t start3; |
398 uint32_t stop3; | 362 uint32_t stop3; |
399 uint32_t start4; | 363 uint32_t start4; |
400 uint32_t stop4; | 364 uint32_t stop4; |
| 365 //Prepare spectrum mask specific variables |
| 366 uint32_t innerSlopeWidth = static_cast<uint32_t>((1e6 / bandBandwidth) + 0.5);
//size in number of subcarriers of the 0dBr<->20dBr slope |
| 367 double lowestPointDbr = (centerFrequency >= 5000) ? |
| 368 -40.0 : //if 5 GHz band |
| 369 -45.0; //if 2.4 GHz band |
| 370 std::vector <StartStop> subBands; //list of data/pilot-containing subBands (se
nt at 0dBr) |
| 371 StartStop maskBand (0, nAllocatedBands + nGuardBands); |
401 switch (channelWidth) | 372 switch (channelWidth) |
402 { | 373 { |
403 case 20: | 374 case 20: |
404 // 242 subcarriers (234 data + 8 pilot) | 375 // 242 subcarriers (234 data + 8 pilot) |
405 txPowerPerBand = txPowerW / 242; | 376 txPowerPerBandW = txPowerW / 242; |
406 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 377 innerSlopeWidth = static_cast<uint32_t>((5e5 / bandBandwidth) + 0.5); // [
-10.25;-9.75] & [9.75;10.25] |
407 // skip the guard band and 11 subbands, then place power in 121 subbands,
then | 378 // skip the guard band and 6 subbands, then place power in 121 subbands, t
hen |
408 // skip 3 DC, then place power in 121 subbands, then skip | 379 // skip 3 DC, then place power in 121 subbands, then skip |
409 // the final 11 subbands and the guard band. | 380 // the final 6 subbands and the guard band. |
410 start1 = (nGuardBands / 2) + 12; | 381 start1 = (nGuardBands / 2) + 6; |
411 stop1 = start1 + 121 - 1; | 382 stop1 = start1 + 121 - 1; |
412 start2 = stop1 + 4; | 383 start2 = stop1 + 4; |
413 stop2 = start2 + 121 - 1; | 384 stop2 = start2 + 121 - 1; |
414 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | 385 subBands.push_back (std::make_pair (start1, stop1)); |
415 { | 386 subBands.push_back (std::make_pair (start2, stop2)); |
416 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2)) | |
417 { | |
418 *vit = txPowerPerBand / (bit->fh - bit->fl); | |
419 } | |
420 else | |
421 { | |
422 *vit = 0; | |
423 } | |
424 } | |
425 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
426 " and " << start2 << "-" << stop2); | |
427 break; | 387 break; |
428 case 40: | 388 case 40: |
429 // 484 subcarriers (468 data + 16 pilot) | 389 // 484 subcarriers (468 data + 16 pilot) |
430 txPowerPerBand = txPowerW / 484; | 390 txPowerPerBandW = txPowerW / 484; |
431 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 391 // skip the guard band and 12 subbands, then place power in 242 subbands,
then |
432 // skip the guard band and 11 subbands, then place power in 242 subbands,
then | |
433 // skip 5 DC, then place power in 242 subbands, then skip | 392 // skip 5 DC, then place power in 242 subbands, then skip |
434 // the final 11 subbands and the guard band. | 393 // the final 12 subbands and the guard band. |
435 start1 = (nGuardBands / 2) + 12; | 394 start1 = (nGuardBands / 2) + 12; |
436 stop1 = start1 + 242 - 1; | 395 stop1 = start1 + 242 - 1; |
437 start2 = stop1 + 6; | 396 start2 = stop1 + 6; |
438 stop2 = start2 + 242 - 1; | 397 stop2 = start2 + 242 - 1; |
439 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | 398 subBands.push_back (std::make_pair (start1, stop1)); |
440 { | 399 subBands.push_back (std::make_pair (start2, stop2)); |
441 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2)) | |
442 { | |
443 *vit = txPowerPerBand / (bit->fh - bit->fl); | |
444 } | |
445 else | |
446 { | |
447 *vit = 0; | |
448 } | |
449 } | |
450 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
451 " and " << start2 << "-" << stop2); | |
452 break; | 400 break; |
453 case 80: | 401 case 80: |
454 // 996 subcarriers (980 data + 16 pilot) | 402 // 996 subcarriers (980 data + 16 pilot) |
455 txPowerPerBand = txPowerW / 996; | 403 txPowerPerBandW = txPowerW / 996; |
456 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | 404 // skip the guard band and 12 subbands, then place power in 498 subbands,
then |
457 // skip the guard band and 11 subbands, then place power in 498 subbands,
then | |
458 // skip 5 DC, then place power in 498 subbands, then skip | 405 // skip 5 DC, then place power in 498 subbands, then skip |
459 // the final 11 subbands and the guard band. | 406 // the final 12 subbands and the guard band. |
460 start1 = (nGuardBands / 2) + 12; | 407 start1 = (nGuardBands / 2) + 12; |
461 stop1 = start1 + 498 - 1; | 408 stop1 = start1 + 498 - 1; |
462 start2 = stop1 + 6; | 409 start2 = stop1 + 6; |
463 stop2 = start2 + 498 - 1; | 410 stop2 = start2 + 498 - 1; |
464 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | 411 subBands.push_back (std::make_pair (start1, stop1)); |
465 { | 412 subBands.push_back (std::make_pair (start2, stop2)); |
466 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2)) | |
467 { | |
468 *vit = txPowerPerBand / (bit->fh - bit->fl); | |
469 } | |
470 else | |
471 { | |
472 *vit = 0; | |
473 } | |
474 } | |
475 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
476 " and " << start2 << "-" << stop2); | |
477 break; | 413 break; |
478 case 160: | 414 case 160: |
479 // 2 x 996 subcarriers (2 x 80 MHZ bands) | 415 // 2 x 996 subcarriers (2 x 80 MHZ bands) |
480 txPowerPerBand = txPowerW / (2 * 996); | 416 txPowerPerBandW = txPowerW / (2 * 996); |
481 NS_LOG_DEBUG ("Power per band " << txPowerPerBand); | |
482 start1 = (nGuardBands / 2) + 12; | 417 start1 = (nGuardBands / 2) + 12; |
483 stop1 = start1 + 498 - 1; | 418 stop1 = start1 + 498 - 1; |
484 start2 = stop1 + 6; | 419 start2 = stop1 + 6; |
485 stop2 = start2 + 498 - 1; | 420 stop2 = start2 + 498 - 1; |
486 start3 = stop2 + (2 * 12); | 421 start3 = stop2 + (2 * 12); |
487 stop3 = start3 + 498 - 1; | 422 stop3 = start3 + 498 - 1; |
488 start4 = stop3 + 6; | 423 start4 = stop3 + 6; |
489 stop4 = start4 + 498 - 1; | 424 stop4 = start4 + 498 - 1; |
490 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++,
bit++) | 425 subBands.push_back (std::make_pair (start1, stop1)); |
491 { | 426 subBands.push_back (std::make_pair (start2, stop2)); |
492 if ((i >= start1 && i <= stop1) || (i >= start2 && i <= stop2) || | 427 subBands.push_back (std::make_pair (start3, stop3)); |
493 (i >= start3 && i <= stop3) || (i >= start4 && i <= stop4)) | 428 subBands.push_back (std::make_pair (start4, stop4)); |
494 { | |
495 *vit = txPowerPerBand / (bit->fh - bit->fl); | |
496 } | |
497 else | |
498 { | |
499 *vit = 0; | |
500 } | |
501 } | |
502 NS_LOG_DEBUG ("Added signal power to subbands " << start1 << "-" << stop1
<< | |
503 ", " << start2 << "-" << stop2 << | |
504 ", " << start3 << "-" << stop3 << | |
505 ", " << start4 << "-" << stop4); | |
506 break; | 429 break; |
507 default: | 430 default: |
508 NS_FATAL_ERROR ("ChannelWidth " << channelWidth << " unsupported"); | 431 NS_FATAL_ERROR ("ChannelWidth " << channelWidth << " unsupported"); |
509 break; | 432 break; |
510 } | 433 } |
511 NS_LOG_DEBUG ("Integrated power " << Integral (*c)); | 434 |
| 435 //Build transmit spectrum mask |
| 436 CreateSpectrumMaskForOfdm (c, subBands, maskBand, |
| 437 txPowerPerBandW, nGuardBands, |
| 438 innerSlopeWidth, lowestPointDbr); |
| 439 NormalizeSpectrumMask (c, txPowerW); |
512 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation f
ailed"); | 440 NS_ASSERT_MSG (std::abs (txPowerW - Integral (*c)) < 1e-6, "Power allocation f
ailed"); |
513 return c; | 441 return c; |
514 } | 442 } |
515 | 443 |
516 Ptr<SpectrumValue> | 444 Ptr<SpectrumValue> |
517 WifiSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t centerFrequen
cy, uint8_t channelWidth, double bandBandwidth, double noiseFigure, uint8_t guar
dBandwidth) | 445 WifiSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t centerFrequen
cy, uint8_t channelWidth, double bandBandwidth, double noiseFigure, uint8_t guar
dBandwidth) |
518 { | 446 { |
519 Ptr<SpectrumModel> model = GetSpectrumModel (centerFrequency, channelWidth, ba
ndBandwidth, guardBandwidth); | 447 Ptr<SpectrumModel> model = GetSpectrumModel (centerFrequency, channelWidth, ba
ndBandwidth, guardBandwidth); |
520 return CreateNoisePowerSpectralDensity (noiseFigure, model); | 448 return CreateNoisePowerSpectralDensity (noiseFigure, model); |
521 } | 449 } |
522 | 450 |
523 Ptr<SpectrumValue> | 451 Ptr<SpectrumValue> |
524 WifiSpectrumValueHelper::CreateNoisePowerSpectralDensity (double noiseFigureDb,
Ptr<SpectrumModel> spectrumModel) | 452 WifiSpectrumValueHelper::CreateNoisePowerSpectralDensity (double noiseFigureDb,
Ptr<SpectrumModel> spectrumModel) |
525 { | 453 { |
526 NS_LOG_FUNCTION (noiseFigureDb << spectrumModel); | 454 NS_LOG_FUNCTION (noiseFigureDb << spectrumModel); |
527 | 455 |
528 // see "LTE - From theory to practice" | 456 // see "LTE - From theory to practice" |
529 // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure | 457 // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure |
530 const double kT_dBm_Hz = -174.0; // dBm/Hz | 458 const double kT_dBm_Hz = -174.0; // dBm/Hz |
531 double kT_W_Hz = std::pow (10.0, (kT_dBm_Hz - 30) / 10.0); | 459 double kT_W_Hz = std::pow (10.0, (kT_dBm_Hz - 30) / 10.0); |
532 double noiseFigureLinear = std::pow (10.0, noiseFigureDb / 10.0); | 460 double noiseFigureLinear = std::pow (10.0, noiseFigureDb / 10.0); |
533 double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear; | 461 double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear; |
534 | 462 |
535 Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (spectrumModel); | 463 Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (spectrumModel); |
536 (*noisePsd) = noisePowerSpectralDensity; | 464 (*noisePsd) = noisePowerSpectralDensity; |
537 NS_LOG_DEBUG ("NoisePowerSpectralDensity has integrated power of " << Integral
(*noisePsd)); | 465 NS_LOG_INFO ("NoisePowerSpectralDensity has integrated power of " << Integral
(*noisePsd)); |
538 return noisePsd; | 466 return noisePsd; |
539 } | 467 } |
540 | 468 |
541 Ptr<SpectrumValue> | 469 Ptr<SpectrumValue> |
542 WifiSpectrumValueHelper::CreateRfFilter (uint32_t centerFrequency, uint8_t chann
elWidth, double bandGranularity, uint8_t guardBandwidth) | 470 WifiSpectrumValueHelper::CreateRfFilter (uint32_t centerFrequency, uint8_t chann
elWidth, double bandGranularity, uint8_t guardBandwidth) |
543 { | 471 { |
544 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << bandGranularity
<< (uint16_t)guardBandwidth); | 472 NS_LOG_FUNCTION (centerFrequency << (uint16_t)channelWidth << bandGranularity
<< (uint16_t)guardBandwidth); |
545 Ptr<SpectrumValue> c = Create <SpectrumValue> (GetSpectrumModel (centerFrequen
cy, channelWidth, bandGranularity, guardBandwidth)); | 473 Ptr<SpectrumValue> c = Create <SpectrumValue> (GetSpectrumModel (centerFrequen
cy, channelWidth, bandGranularity, guardBandwidth)); |
546 size_t numBands = c->GetSpectrumModel ()->GetNumBands (); | 474 size_t numBands = c->GetSpectrumModel ()->GetNumBands (); |
547 Bands::const_iterator bit = c->ConstBandsBegin (); | 475 Bands::const_iterator bit = c->ConstBandsBegin (); |
548 Values::iterator vit = c->ValuesBegin (); | 476 Values::iterator vit = c->ValuesBegin (); |
549 uint32_t bandBandwidth = static_cast<uint32_t> (bandGranularity); | 477 uint32_t bandBandwidth = static_cast<uint32_t> (bandGranularity); |
550 size_t numBandsInFilter = static_cast<size_t> (channelWidth * 1e6 / bandBandwi
dth);· | 478 size_t numBandsInFilter = static_cast<size_t> (channelWidth * 1e6 / bandBandwi
dth);· |
551 if (channelWidth % bandBandwidth != 0) | 479 if (channelWidth % bandBandwidth != 0) |
552 { | 480 { |
553 numBandsInFilter += 1; | 481 numBandsInFilter += 1; |
554 } | 482 } |
555 NS_LOG_DEBUG ("Num bands in filter: " << numBandsInFilter); | 483 NS_LOG_INFO ("Num bands in filter: " << numBandsInFilter); |
556 // Set the value of the filter to 1 for the center-most numBandsInFilter | 484 // Set the value of the filter to 1 for the center-most numBandsInFilter |
557 NS_ASSERT_MSG ((numBandsInFilter % 2 == 1) && (numBands % 2 == 1), "Should hav
e odd number of bands"); | 485 NS_ASSERT_MSG ((numBandsInFilter % 2 == 1) && (numBands % 2 == 1), "Should hav
e odd number of bands"); |
558 size_t startIndex = (numBands - numBandsInFilter) / 2; | 486 size_t startIndex = (numBands - numBandsInFilter) / 2; |
559 vit += startIndex; | 487 vit += startIndex; |
560 bit += startIndex; | 488 bit += startIndex; |
561 for (size_t i = startIndex; i < startIndex + numBandsInFilter; i++, vit++, bit
++) | 489 for (size_t i = startIndex; i < startIndex + numBandsInFilter; i++, vit++, bit
++) |
562 { | 490 { |
563 *vit = 1; | 491 *vit = 1; |
564 } | 492 } |
565 NS_LOG_DEBUG ("Added subbands " << startIndex << " to " << startIndex + numBan
dsInFilter << " to filter"); | 493 NS_LOG_LOGIC ("Added subbands " << startIndex << " to " << startIndex + numBan
dsInFilter << " to filter"); |
566 return c; | 494 return c; |
567 } | 495 } |
568 | 496 |
| 497 void |
| 498 WifiSpectrumValueHelper::CreateSpectrumMaskForOfdm (Ptr<SpectrumValue> c, std::v
ector <StartStop> allocatedSubBands, StartStop maskBand, |
| 499 double txPowerPerBandW, uint
32_t nGuardBands, |
| 500 uint32_t innerSlopeWidth, do
uble lowestPointDbr) |
| 501 { |
| 502 NS_LOG_FUNCTION (c << allocatedSubBands.front ().first << allocatedSubBands.ba
ck ().second << maskBand.first << maskBand.second << txPowerPerBandW << nGuardBa
nds << innerSlopeWidth << lowestPointDbr); |
| 503 uint32_t numSubBands = allocatedSubBands.size (); |
| 504 uint32_t numBands = c->GetSpectrumModel ()->GetNumBands (); |
| 505 uint32_t numMaskBands = maskBand.second - maskBand.first + 1; |
| 506 NS_ASSERT (numSubBands && numBands && numMaskBands); |
| 507 NS_LOG_LOGIC ("Power per band " << txPowerPerBandW << "W"); |
| 508 |
| 509 //Different power levels |
| 510 double txPowerRefDbm = (10.0 * std::log10 (txPowerPerBandW * 1000.0)); |
| 511 double txPowerInnerBandMinDbm = txPowerRefDbm - 20; |
| 512 double txPowerMiddleBandMinDbm = txPowerRefDbm - 28; |
| 513 double txPowerOuterBandMinDbm = txPowerRefDbm + lowestPointDbr; //TODO also ta
ke into account dBm/MHz constraints |
| 514 |
| 515 //Different widths (in number of bands) |
| 516 uint32_t outerSlopeWidth = nGuardBands / 4; // nGuardBands is the total left+r
ight guard band. The left/right outer part is half of the left/right guard band. |
| 517 uint32_t middleSlopeWidth = outerSlopeWidth - (innerSlopeWidth / 2); |
| 518 StartStop outerBandLeft (maskBand.first, //to handle cases where allocated cha
nnel is under WifiPhy configured channel width. |
| 519 maskBand.first + outerSlopeWidth - 1); |
| 520 StartStop middleBandLeft (outerBandLeft.second + 1, |
| 521 outerBandLeft.second + middleSlopeWidth); |
| 522 StartStop innerBandLeft (allocatedSubBands.front ().first - innerSlopeWidth, |
| 523 allocatedSubBands.front ().first - 1); //better to pl
ace slope based on allocated subcarriers |
| 524 StartStop flatJunctionLeft (middleBandLeft.second + 1, |
| 525 innerBandLeft.first - 1); //in order to handle shi
ft due to guard subcarriers |
| 526 StartStop outerBandRight (maskBand.second - outerSlopeWidth + 1, |
| 527 maskBand.second); //start from outer edge to be able
to compute flat junction width |
| 528 StartStop middleBandRight (outerBandRight.first - middleSlopeWidth, |
| 529 outerBandRight.first - 1); |
| 530 StartStop innerBandRight (allocatedSubBands.back ().second + 1, |
| 531 allocatedSubBands.back ().second + innerSlopeWidth); |
| 532 StartStop flatJunctionRight (innerBandRight.second + 1, |
| 533 middleBandRight.first - 1); |
| 534 NS_LOG_DEBUG ("outerBandLeft=[" << outerBandLeft.first << ";" << outerBandLeft
.second << "] " << |
| 535 "middleBandLeft=[" << middleBandLeft.first << ";" << middleBandL
eft.second << "] " << |
| 536 "flatJunctionLeft=[" << flatJunctionLeft.first << ";" << flatJun
ctionLeft.second << "] " << |
| 537 "innerBandLeft=[" << innerBandLeft.first << ";" << innerBandLeft
.second << "] " << |
| 538 "subBands=[" << allocatedSubBands.front ().first << ";" << alloc
atedSubBands.back ().second << "] " << |
| 539 "innerBandRight=[" << innerBandRight.first << ";" << innerBandRi
ght.second << "] " << |
| 540 "flatJunctionRight=[" << flatJunctionRight.first << ";" << flatJ
unctionRight.second << "] " << |
| 541 "middleBandRight=[" << middleBandRight.first << ";" << middleBan
dRight.second << "] " << |
| 542 "outerBandRight=[" << outerBandRight.first << ";" << outerBandRi
ght.second << "] "); |
| 543 NS_ASSERT (numMaskBands == ((allocatedSubBands.back ().second - allocatedSubBa
nds.front ().first + 1) //equivalent to allocatedBand (includes notches and DC) |
| 544 + 2 * (innerSlopeWidth + middleSlopeWidth + outerSl
opeWidth) |
| 545 + (flatJunctionLeft.second - flatJunctionLeft.first
+ 1) //flat junctions |
| 546 + (flatJunctionRight.second - flatJunctionRight.fir
st + 1))); |
| 547 |
| 548 //Different slopes |
| 549 double innerSlope = 20.0 / innerSlopeWidth; //0 to 20dBr |
| 550 double middleSlope = 8.0 / middleSlopeWidth; //20 to 28dBr |
| 551 double outerSlope = (txPowerMiddleBandMinDbm - txPowerOuterBandMinDbm) / outer
SlopeWidth; |
| 552 |
| 553 //Build spectrum mask |
| 554 Values::iterator vit = c->ValuesBegin (); |
| 555 Bands::const_iterator bit = c->ConstBandsBegin (); |
| 556 double txPowerW = 0.0; |
| 557 for (size_t i = 0; i < numBands; i++, vit++, bit++) |
| 558 { |
| 559 if (i < maskBand.first || i > maskBand.second) //outside the spectrum mask |
| 560 { |
| 561 txPowerW = 0.0; |
| 562 } |
| 563 else if (i <= outerBandLeft.second && i >= outerBandLeft.first) //better t
o put greater first (less computation) |
| 564 { |
| 565 txPowerW = DbmToW (txPowerOuterBandMinDbm + ((i - outerBandLeft.first)
* outerSlope)); |
| 566 } |
| 567 else if (i <= middleBandLeft.second && i >= middleBandLeft.first) |
| 568 { |
| 569 txPowerW = DbmToW (txPowerMiddleBandMinDbm + ((i - middleBandLeft.firs
t) * middleSlope)); |
| 570 } |
| 571 else if (i <= flatJunctionLeft.second && i >= flatJunctionLeft.first) |
| 572 { |
| 573 txPowerW = DbmToW (txPowerInnerBandMinDbm); |
| 574 } |
| 575 else if (i <= innerBandLeft.second && i >= innerBandLeft.first) |
| 576 { |
| 577 txPowerW = DbmToW (txPowerInnerBandMinDbm + ((i - innerBandLeft.first)
* innerSlope)); |
| 578 } |
| 579 else if (i <= allocatedSubBands.back ().second && i >= allocatedSubBands.f
ront ().first) //roughly in allocated band |
| 580 { |
| 581 bool insideSubBand = false; |
| 582 for (uint32_t j = 0; !insideSubBand && j < numSubBands; j++) //continu
e until inside a sub-band |
| 583 { |
| 584 insideSubBand = (i <= allocatedSubBands[j].second) && (i >= alloca
tedSubBands[j].first); |
| 585 } |
| 586 if (insideSubBand) |
| 587 { |
| 588 txPowerW = txPowerPerBandW; |
| 589 } |
| 590 else |
| 591 { |
| 592 txPowerW = DbmToW (txPowerInnerBandMinDbm); //consider that nulled
as much as possible inband but power leakage -> -20dBr |
| 593 } |
| 594 } |
| 595 else if (i <= innerBandRight.second && i >= innerBandRight.first) |
| 596 { |
| 597 txPowerW = DbmToW (txPowerRefDbm - ((i - innerBandRight.first + 1) * i
nnerSlope)); // +1 so as to be symmetric with left slope |
| 598 } |
| 599 else if (i <= flatJunctionRight.second && i >= flatJunctionRight.first) |
| 600 { |
| 601 txPowerW = DbmToW (txPowerInnerBandMinDbm); |
| 602 } |
| 603 else if (i <= middleBandRight.second && i >= middleBandRight.first) |
| 604 { |
| 605 txPowerW = DbmToW (txPowerInnerBandMinDbm - ((i - middleBandRight.firs
t + 1) * middleSlope)); // +1 so as to be symmetric with left slope |
| 606 } |
| 607 else if (i <= outerBandRight.second && i >= outerBandRight.first) |
| 608 { |
| 609 txPowerW = DbmToW (txPowerMiddleBandMinDbm - ((i - outerBandRight.firs
t + 1) * outerSlope)); // +1 so as to be symmetric with left slope |
| 610 } |
| 611 else |
| 612 { |
| 613 NS_FATAL_ERROR ("Should have handled all cases"); |
| 614 } |
| 615 double txPowerDbr = 10 * std::log10 (txPowerW / txPowerPerBandW); |
| 616 NS_LOG_LOGIC (uint32_t(i) << " -> " << txPowerDbr); |
| 617 *vit = txPowerW / (bit->fh - bit->fl); |
| 618 } |
| 619 NS_LOG_INFO ("Added signal power to subbands " << allocatedSubBands.front ().f
irst << "-" << allocatedSubBands.back ().second); |
| 620 } |
| 621 |
| 622 void |
| 623 WifiSpectrumValueHelper::NormalizeSpectrumMask (Ptr<SpectrumValue> c, double txP
owerW) |
| 624 { |
| 625 NS_LOG_FUNCTION (c << txPowerW); |
| 626 //Normalize power so that total signal power equals transmit power |
| 627 double currentTxPowerW = Integral (*c); |
| 628 double normalizationRatio = currentTxPowerW / txPowerW; |
| 629 NS_LOG_LOGIC ("Current power: " << currentTxPowerW << "W vs expected power: "
<< txPowerW << "W" << |
| 630 " -> ratio (C/E) = " << normalizationRatio); |
| 631 Values::iterator vit = c->ValuesBegin (); |
| 632 for (size_t i = 0; i < c->GetSpectrumModel ()->GetNumBands (); i++, vit++) |
| 633 { |
| 634 *vit = (*vit) / normalizationRatio; |
| 635 } |
| 636 } |
| 637 |
| 638 double |
| 639 WifiSpectrumValueHelper::DbmToW (double dBm) |
| 640 { |
| 641 double mW = std::pow (10.0, dBm / 10.0); |
| 642 return mW / 1000.0; |
| 643 } |
| 644 |
569 static Ptr<SpectrumModel> g_WifiSpectrumModel5Mhz; ///< static initializer for t
he class | 645 static Ptr<SpectrumModel> g_WifiSpectrumModel5Mhz; ///< static initializer for t
he class |
570 | 646 |
571 WifiSpectrumValueHelper::~WifiSpectrumValueHelper () | 647 WifiSpectrumValueHelper::~WifiSpectrumValueHelper () |
572 { | 648 { |
573 } | 649 } |
574 | 650 |
575 WifiSpectrumValue5MhzFactory::~WifiSpectrumValue5MhzFactory () | 651 WifiSpectrumValue5MhzFactory::~WifiSpectrumValue5MhzFactory () |
576 { | 652 { |
577 } | 653 } |
578 | 654 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 (*rf)[channel + 3] = 1; | 729 (*rf)[channel + 3] = 1; |
654 (*rf)[channel + 4] = 1; | 730 (*rf)[channel + 4] = 1; |
655 (*rf)[channel + 5] = 1; | 731 (*rf)[channel + 5] = 1; |
656 (*rf)[channel + 6] = 1; | 732 (*rf)[channel + 6] = 1; |
657 | 733 |
658 return rf; | 734 return rf; |
659 } | 735 } |
660 | 736 |
661 | 737 |
662 } // namespace ns3 | 738 } // namespace ns3 |
OLD | NEW |