A Discrete-Event Network Simulator
API
lte-spectrum-value-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
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: Giuseppe Piro <g.piro@poliba.it>
18 * Nicola Baldo <nbaldo@cttc.es>
19 */
20
22
23#include <ns3/fatal-error.h>
24#include <ns3/log.h>
25
26#include <cmath>
27#include <map>
28
29// just needed to log a std::vector<int> properly...
30namespace std
31{
32
43ostream&
44operator<<(ostream& os, const vector<int>& v)
45{
46 vector<int>::const_iterator it = v.begin();
47 while (it != v.end())
48 {
49 os << *it << " ";
50 ++it;
51 }
52 os << endl;
53 return os;
54}
55
56} // namespace std
57
58namespace ns3
59{
60
61NS_LOG_COMPONENT_DEFINE("LteSpectrumValueHelper");
62
69static const struct EutraChannelNumbers
70{
71 uint8_t band;
72 double fDlLow;
76 double fUlLow;
81 {1, 2110, 0, 0, 599, 1920, 18000, 18000, 18599},
82 {2, 1930, 600, 600, 1199, 1850, 18600, 18600, 19199},
83 {3, 1805, 1200, 1200, 1949, 1710, 19200, 19200, 19949},
84 {4, 2110, 1950, 1950, 2399, 1710, 19950, 19950, 20399},
85 {5, 869, 2400, 2400, 2649, 824, 20400, 20400, 20649},
86 {6, 875, 2650, 2650, 2749, 830, 20650, 20650, 20749},
87 {7, 2620, 2750, 2750, 3449, 2500, 20750, 20750, 21449},
88 {8, 925, 3450, 3450, 3799, 880, 21450, 21450, 21799},
89 {9, 1844.9, 3800, 3800, 4149, 1749.9, 21800, 21800, 22149},
90 {10, 2110, 4150, 4150, 4749, 1710, 22150, 22150, 22749},
91 {11, 1475.9, 4750, 4750, 4949, 1427.9, 22750, 22750, 22949},
92 {12, 728, 5000, 5000, 5179, 698, 23000, 23000, 23179},
93 {13, 746, 5180, 5180, 5279, 777, 23180, 23180, 23279},
94 {14, 758, 5280, 5280, 5379, 788, 23280, 23280, 23379},
95 {17, 734, 5730, 5730, 5849, 704, 23730, 23730, 23849},
96 {18, 860, 5850, 5850, 5999, 815, 23850, 23850, 23999},
97 {19, 875, 6000, 6000, 6149, 830, 24000, 24000, 24149},
98 {20, 791, 6150, 6150, 6449, 832, 24150, 24150, 24449},
99 {21, 1495.9, 6450, 6450, 6599, 1447.9, 24450, 24450, 24599},
100 {33, 1900, 36000, 36000, 36199, 1900, 36000, 36000, 36199},
101 {34, 2010, 36200, 36200, 36349, 2010, 36200, 36200, 36349},
102 {35, 1850, 36350, 36350, 36949, 1850, 36350, 36350, 36949},
103 {36, 1930, 36950, 36950, 37549, 1930, 36950, 36950, 37549},
104 {37, 1910, 37550, 37550, 37749, 1910, 37550, 37550, 37749},
105 {38, 2570, 37750, 37750, 38249, 2570, 37750, 37750, 38249},
106 {39, 1880, 38250, 38250, 38649, 1880, 38250, 38250, 38649},
107 {40, 2300, 38650, 38650, 39649, 2300, 38650, 38650, 39649}};
108
110#define NUM_EUTRA_BANDS (sizeof(g_eutraChannelNumbers) / sizeof(EutraChannelNumbers))
111
112double
114{
115 NS_LOG_FUNCTION(earfcn);
116 if (earfcn < 7000)
117 {
118 // FDD downlink
119 return GetDownlinkCarrierFrequency(earfcn);
120 }
121 else
122 {
123 // either FDD uplink or TDD (for which uplink & downlink have same frequency)
124 return GetUplinkCarrierFrequency(earfcn);
125 }
126}
127
128uint16_t
130{
131 NS_LOG_FUNCTION(nDl);
132 for (uint32_t i = 0; i < NUM_EUTRA_BANDS; ++i)
133 {
134 if (g_eutraChannelNumbers[i].rangeNdl1 <= nDl && g_eutraChannelNumbers[i].rangeNdl2 >= nDl)
135 {
136 NS_LOG_LOGIC("entry " << i << " fDlLow=" << g_eutraChannelNumbers[i].fDlLow);
137 return i;
138 }
139 }
140 NS_LOG_ERROR("invalid EARFCN " << nDl);
141 return NUM_EUTRA_BANDS;
142}
143
144uint16_t
146{
147 NS_LOG_FUNCTION(nUl);
148 for (uint32_t i = 0; i < NUM_EUTRA_BANDS; ++i)
149 {
150 if (g_eutraChannelNumbers[i].rangeNul1 <= nUl && g_eutraChannelNumbers[i].rangeNul2 >= nUl)
151 {
152 NS_LOG_LOGIC("entry " << i << " fUlLow=" << g_eutraChannelNumbers[i].fUlLow);
153 return i;
154 }
155 }
156 NS_LOG_ERROR("invalid EARFCN " << nUl);
157 return NUM_EUTRA_BANDS;
158}
159
160double
162{
163 NS_LOG_FUNCTION(nDl);
164 uint16_t i = GetDownlinkCarrierBand(nDl);
165 if (i == NUM_EUTRA_BANDS)
166 {
167 return 0.0;
168 }
169 return 1.0e6 *
171}
172
173double
175{
176 NS_LOG_FUNCTION(nUl);
177 uint16_t i = GetUplinkCarrierBand(nUl);
178 if (i == NUM_EUTRA_BANDS)
179 {
180 return 0.0;
181 }
182 return 1.0e6 *
184}
185
186double
187LteSpectrumValueHelper::GetChannelBandwidth(uint16_t transmissionBandwidth)
188{
189 NS_LOG_FUNCTION(transmissionBandwidth);
190 switch (transmissionBandwidth)
191 {
192 case 6:
193 return 1.4e6;
194 case 15:
195 return 3.0e6;
196 case 25:
197 return 5.0e6;
198 case 50:
199 return 10.0e6;
200 case 75:
201 return 15.0e6;
202 case 100:
203 return 20.0e6;
204 default:
205 NS_FATAL_ERROR("invalid bandwidth value " << transmissionBandwidth);
206 }
207}
208
211{
218 LteSpectrumModelId(uint32_t f, uint8_t b);
220 uint16_t bandwidth;
221};
222
224 : earfcn(f),
225 bandwidth(b)
226{
227}
228
236bool
238{
239 return ((a.earfcn < b.earfcn) || ((a.earfcn == b.earfcn) && (a.bandwidth < b.bandwidth)));
240}
241
242static std::map<LteSpectrumModelId, Ptr<SpectrumModel>>
244
246LteSpectrumValueHelper::GetSpectrumModel(uint32_t earfcn, uint16_t txBandwidthConfiguration)
247{
248 NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration);
250 LteSpectrumModelId key(earfcn, txBandwidthConfiguration);
251 std::map<LteSpectrumModelId, Ptr<SpectrumModel>>::iterator it = g_lteSpectrumModelMap.find(key);
252 if (it != g_lteSpectrumModelMap.end())
253 {
254 ret = it->second;
255 }
256 else
257 {
258 double fc = GetCarrierFrequency(earfcn);
259 NS_ASSERT_MSG(fc != 0, "invalid EARFCN=" << earfcn);
260
261 double f = fc - (txBandwidthConfiguration * 180e3 / 2.0);
262 Bands rbs;
263 for (uint16_t numrb = 0; numrb < txBandwidthConfiguration; ++numrb)
264 {
265 BandInfo rb;
266 rb.fl = f;
267 f += 90e3;
268 rb.fc = f;
269 f += 90e3;
270 rb.fh = f;
271 rbs.push_back(rb);
272 }
273 ret = Create<SpectrumModel>(rbs);
274 g_lteSpectrumModelMap.insert(std::pair<LteSpectrumModelId, Ptr<SpectrumModel>>(key, ret));
275 }
276 NS_LOG_LOGIC("returning SpectrumModel::GetUid () == " << ret->GetUid());
277 return ret;
278}
279
282 uint16_t txBandwidthConfiguration,
283 double powerTx,
284 std::vector<int> activeRbs)
285{
286 NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << powerTx << activeRbs);
287
288 Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
289 Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
290
291 // powerTx is expressed in dBm. We must convert it into natural unit.
292 double powerTxW = std::pow(10., (powerTx - 30) / 10);
293
294 double txPowerDensity = (powerTxW / (txBandwidthConfiguration * 180000));
295
296 for (std::vector<int>::iterator it = activeRbs.begin(); it != activeRbs.end(); it++)
297 {
298 int rbId = (*it);
299 (*txPsd)[rbId] = txPowerDensity;
300 }
301
302 NS_LOG_LOGIC(*txPsd);
303
304 return txPsd;
305}
306
309 uint16_t txBandwidthConfiguration,
310 double powerTx,
311 std::map<int, double> powerTxMap,
312 std::vector<int> activeRbs)
313{
314 NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << activeRbs);
315
316 Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
317 Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
318
319 // powerTx is expressed in dBm. We must convert it into natural unit.
320 double basicPowerTxW = std::pow(10., (powerTx - 30) / 10);
321
322 for (std::vector<int>::iterator it = activeRbs.begin(); it != activeRbs.end(); it++)
323 {
324 int rbId = (*it);
325
326 std::map<int, double>::iterator powerIt = powerTxMap.find(rbId);
327
328 double txPowerDensity;
329
330 if (powerIt != powerTxMap.end())
331 {
332 double powerTxW = std::pow(10., (powerIt->second - 30) / 10);
333 txPowerDensity = (powerTxW / (txBandwidthConfiguration * 180000));
334 }
335 else
336 {
337 txPowerDensity = (basicPowerTxW / (txBandwidthConfiguration * 180000));
338 }
339
340 (*txPsd)[rbId] = txPowerDensity;
341 }
342
343 NS_LOG_LOGIC(*txPsd);
344
345 return txPsd;
346}
347
350 uint16_t txBandwidthConfiguration,
351 double powerTx,
352 std::vector<int> activeRbs)
353{
354 NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << powerTx << activeRbs);
355
356 Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
357 Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
358
359 // powerTx is expressed in dBm. We must convert it into natural unit.
360 double powerTxW = std::pow(10., (powerTx - 30) / 10);
361
362 double txPowerDensity = (powerTxW / (activeRbs.size() * 180000));
363
364 for (std::vector<int>::iterator it = activeRbs.begin(); it != activeRbs.end(); it++)
365 {
366 int rbId = (*it);
367 (*txPsd)[rbId] = txPowerDensity;
368 }
369
370 NS_LOG_LOGIC(*txPsd);
371
372 return txPsd;
373}
374
377 uint16_t txBandwidthConfiguration,
378 double noiseFigure)
379{
380 NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << noiseFigure);
381 Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
382 return CreateNoisePowerSpectralDensity(noiseFigure, model);
383}
384
387 Ptr<SpectrumModel> spectrumModel)
388{
389 NS_LOG_FUNCTION(noiseFigureDb << spectrumModel);
390
391 // see "LTE - From theory to practice"
392 // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
393 const double kT_dBm_Hz = -174.0; // dBm/Hz
394 double kT_W_Hz = std::pow(10.0, (kT_dBm_Hz - 30) / 10.0);
395 double noiseFigureLinear = std::pow(10.0, noiseFigureDb / 10.0);
396 double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
397
398 Ptr<SpectrumValue> noisePsd = Create<SpectrumValue>(spectrumModel);
399 (*noisePsd) = noisePowerSpectralDensity;
400 return noisePsd;
401}
402
403} // namespace ns3
double f(double x, void *params)
Definition: 80211b.c:71
static Ptr< SpectrumValue > CreateUlTxPowerSpectralDensity(uint16_t earfcn, uint16_t bandwidth, double powerTx, std::vector< int > activeRbs)
create a spectrum value representing the uplink power spectral density of a signal to be transmitted.
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double powerTx, std::vector< int > activeRbs)
create a spectrum value representing the power spectral density of a signal to be transmitted.
static uint16_t GetUplinkCarrierBand(uint32_t nUl)
Converts uplink EARFCN to corresponding LTE frequency band number.
static uint16_t GetDownlinkCarrierBand(uint32_t nDl)
Converts downlink EARFCN to corresponding LTE frequency band number.
static double GetChannelBandwidth(uint16_t txBandwidthConf)
static double GetUplinkCarrierFrequency(uint32_t earfcn)
Calculates the uplink carrier frequency from the E-UTRA Absolute Radio Frequency Channel Number (EARF...
static double GetCarrierFrequency(uint32_t earfcn)
Calculates the carrier frequency from the E-UTRA Absolute Radio Frequency Channel Number (EARFCN) acc...
static Ptr< SpectrumModel > GetSpectrumModel(uint32_t earfcn, uint16_t bandwidth)
static double GetDownlinkCarrierFrequency(uint32_t earfcn)
Calculates the downlink carrier frequency from the E-UTRA Absolute Radio Frequency Channel Number (EA...
SpectrumModelUid_t GetUid() const
#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:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NUM_EUTRA_BANDS
number of EUTRA bands
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static std::map< LteSpectrumModelId, Ptr< SpectrumModel > > g_lteSpectrumModelMap
LTE spectrum model map.
std::vector< BandInfo > Bands
Container of BandInfo.
static const struct ns3::EutraChannelNumbers g_eutraChannelNumbers[]
eutra channel numbers
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
STL namespace.
ostream & operator<<(ostream &os, const vector< int > &v)
Stream insertion operator.
The building block of a SpectrumModel.
double fc
center frequency
double fl
lower limit of subband
double fh
upper limit of subband
Table 5.7.3-1 "E-UTRA channel numbers" from 3GPP TS 36.101 The table was converted to C syntax doing ...
uint32_t nOffsDl
number offset DL
uint32_t nOffsUl
number offset UL
LteSpectrumModelId structure.
LteSpectrumModelId(uint32_t f, uint8_t b)
Constructor.