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...
30 namespace std
31 {
32 
43 ostream&
44 operator<<(ostream& os, const vector<int>& v)
45 {
46  auto 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 
58 namespace ns3
59 {
60 
61 NS_LOG_COMPONENT_DEFINE("LteSpectrumValueHelper");
62 
70 {
71  uint8_t band;
72  double fDlLow;
73  uint32_t nOffsDl;
74  uint32_t rangeNdl1;
75  uint32_t rangeNdl2;
76  double fUlLow;
77  uint32_t nOffsUl;
78  uint32_t rangeNul1;
79  uint32_t rangeNul2;
80 };
81 
84  {1, 2110, 0, 0, 599, 1920, 18000, 18000, 18599},
85  {2, 1930, 600, 600, 1199, 1850, 18600, 18600, 19199},
86  {3, 1805, 1200, 1200, 1949, 1710, 19200, 19200, 19949},
87  {4, 2110, 1950, 1950, 2399, 1710, 19950, 19950, 20399},
88  {5, 869, 2400, 2400, 2649, 824, 20400, 20400, 20649},
89  {6, 875, 2650, 2650, 2749, 830, 20650, 20650, 20749},
90  {7, 2620, 2750, 2750, 3449, 2500, 20750, 20750, 21449},
91  {8, 925, 3450, 3450, 3799, 880, 21450, 21450, 21799},
92  {9, 1844.9, 3800, 3800, 4149, 1749.9, 21800, 21800, 22149},
93  {10, 2110, 4150, 4150, 4749, 1710, 22150, 22150, 22749},
94  {11, 1475.9, 4750, 4750, 4949, 1427.9, 22750, 22750, 22949},
95  {12, 728, 5000, 5000, 5179, 698, 23000, 23000, 23179},
96  {13, 746, 5180, 5180, 5279, 777, 23180, 23180, 23279},
97  {14, 758, 5280, 5280, 5379, 788, 23280, 23280, 23379},
98  {17, 734, 5730, 5730, 5849, 704, 23730, 23730, 23849},
99  {18, 860, 5850, 5850, 5999, 815, 23850, 23850, 23999},
100  {19, 875, 6000, 6000, 6149, 830, 24000, 24000, 24149},
101  {20, 791, 6150, 6150, 6449, 832, 24150, 24150, 24449},
102  {21, 1495.9, 6450, 6450, 6599, 1447.9, 24450, 24450, 24599},
103  {33, 1900, 36000, 36000, 36199, 1900, 36000, 36000, 36199},
104  {34, 2010, 36200, 36200, 36349, 2010, 36200, 36200, 36349},
105  {35, 1850, 36350, 36350, 36949, 1850, 36350, 36350, 36949},
106  {36, 1930, 36950, 36950, 37549, 1930, 36950, 36950, 37549},
107  {37, 1910, 37550, 37550, 37749, 1910, 37550, 37550, 37749},
108  {38, 2570, 37750, 37750, 38249, 2570, 37750, 37750, 38249},
109  {39, 1880, 38250, 38250, 38649, 1880, 38250, 38250, 38649},
110  {40, 2300, 38650, 38650, 39649, 2300, 38650, 38650, 39649},
111 };
112 
114 #define NUM_EUTRA_BANDS (sizeof(g_eutraChannelNumbers) / sizeof(EutraChannelNumbers))
115 
116 double
118 {
119  NS_LOG_FUNCTION(earfcn);
120  if (earfcn < 7000)
121  {
122  // FDD downlink
123  return GetDownlinkCarrierFrequency(earfcn);
124  }
125  else
126  {
127  // either FDD uplink or TDD (for which uplink & downlink have same frequency)
128  return GetUplinkCarrierFrequency(earfcn);
129  }
130 }
131 
132 uint16_t
134 {
135  NS_LOG_FUNCTION(nDl);
136  for (uint32_t i = 0; i < NUM_EUTRA_BANDS; ++i)
137  {
138  if (g_eutraChannelNumbers[i].rangeNdl1 <= nDl && g_eutraChannelNumbers[i].rangeNdl2 >= nDl)
139  {
140  NS_LOG_LOGIC("entry " << i << " fDlLow=" << g_eutraChannelNumbers[i].fDlLow);
141  return i;
142  }
143  }
144  NS_LOG_ERROR("invalid EARFCN " << nDl);
145  return NUM_EUTRA_BANDS;
146 }
147 
148 uint16_t
150 {
151  NS_LOG_FUNCTION(nUl);
152  for (uint32_t i = 0; i < NUM_EUTRA_BANDS; ++i)
153  {
154  if (g_eutraChannelNumbers[i].rangeNul1 <= nUl && g_eutraChannelNumbers[i].rangeNul2 >= nUl)
155  {
156  NS_LOG_LOGIC("entry " << i << " fUlLow=" << g_eutraChannelNumbers[i].fUlLow);
157  return i;
158  }
159  }
160  NS_LOG_ERROR("invalid EARFCN " << nUl);
161  return NUM_EUTRA_BANDS;
162 }
163 
164 double
166 {
167  NS_LOG_FUNCTION(nDl);
168  uint16_t i = GetDownlinkCarrierBand(nDl);
169  if (i == NUM_EUTRA_BANDS)
170  {
171  return 0.0;
172  }
173  return 1.0e6 *
175 }
176 
177 double
179 {
180  NS_LOG_FUNCTION(nUl);
181  uint16_t i = GetUplinkCarrierBand(nUl);
182  if (i == NUM_EUTRA_BANDS)
183  {
184  return 0.0;
185  }
186  return 1.0e6 *
188 }
189 
190 double
191 LteSpectrumValueHelper::GetChannelBandwidth(uint16_t transmissionBandwidth)
192 {
193  NS_LOG_FUNCTION(transmissionBandwidth);
194  switch (transmissionBandwidth)
195  {
196  case 6:
197  return 1.4e6;
198  case 15:
199  return 3.0e6;
200  case 25:
201  return 5.0e6;
202  case 50:
203  return 10.0e6;
204  case 75:
205  return 15.0e6;
206  case 100:
207  return 20.0e6;
208  default:
209  NS_FATAL_ERROR("invalid bandwidth value " << transmissionBandwidth);
210  }
211 }
212 
215 {
222  LteSpectrumModelId(uint32_t f, uint8_t b);
223  uint32_t earfcn;
224  uint16_t bandwidth;
225 };
226 
228  : earfcn(f),
229  bandwidth(b)
230 {
231 }
232 
240 bool
242 {
243  return ((a.earfcn < b.earfcn) || ((a.earfcn == b.earfcn) && (a.bandwidth < b.bandwidth)));
244 }
245 
246 static std::map<LteSpectrumModelId, Ptr<SpectrumModel>>
248 
250 LteSpectrumValueHelper::GetSpectrumModel(uint32_t earfcn, uint16_t txBandwidthConfiguration)
251 {
252  NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration);
253  Ptr<SpectrumModel> ret;
254  LteSpectrumModelId key(earfcn, txBandwidthConfiguration);
255  auto it = g_lteSpectrumModelMap.find(key);
256  if (it != g_lteSpectrumModelMap.end())
257  {
258  ret = it->second;
259  }
260  else
261  {
262  double fc = GetCarrierFrequency(earfcn);
263  NS_ASSERT_MSG(fc != 0, "invalid EARFCN=" << earfcn);
264 
265  double f = fc - (txBandwidthConfiguration * 180e3 / 2.0);
266  Bands rbs;
267  for (uint16_t numrb = 0; numrb < txBandwidthConfiguration; ++numrb)
268  {
269  BandInfo rb;
270  rb.fl = f;
271  f += 90e3;
272  rb.fc = f;
273  f += 90e3;
274  rb.fh = f;
275  rbs.push_back(rb);
276  }
277  ret = Create<SpectrumModel>(rbs);
278  g_lteSpectrumModelMap.insert(std::pair<LteSpectrumModelId, Ptr<SpectrumModel>>(key, ret));
279  }
280  NS_LOG_LOGIC("returning SpectrumModel::GetUid () == " << ret->GetUid());
281  return ret;
282 }
283 
286  uint16_t txBandwidthConfiguration,
287  double powerTx,
288  std::vector<int> activeRbs)
289 {
290  NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << powerTx << activeRbs);
291 
292  Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
293  Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
294 
295  // powerTx is expressed in dBm. We must convert it into natural unit.
296  double powerTxW = std::pow(10., (powerTx - 30) / 10);
297 
298  double txPowerDensity = (powerTxW / (txBandwidthConfiguration * 180000));
299 
300  for (auto it = activeRbs.begin(); it != activeRbs.end(); it++)
301  {
302  int rbId = (*it);
303  (*txPsd)[rbId] = txPowerDensity;
304  }
305 
306  NS_LOG_LOGIC(*txPsd);
307 
308  return txPsd;
309 }
310 
313  uint16_t txBandwidthConfiguration,
314  double powerTx,
315  std::map<int, double> powerTxMap,
316  std::vector<int> activeRbs)
317 {
318  NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << activeRbs);
319 
320  Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
321  Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
322 
323  // powerTx is expressed in dBm. We must convert it into natural unit.
324  double basicPowerTxW = std::pow(10., (powerTx - 30) / 10);
325 
326  for (auto it = activeRbs.begin(); it != activeRbs.end(); it++)
327  {
328  int rbId = (*it);
329 
330  auto powerIt = powerTxMap.find(rbId);
331 
332  double txPowerDensity;
333 
334  if (powerIt != powerTxMap.end())
335  {
336  double powerTxW = std::pow(10., (powerIt->second - 30) / 10);
337  txPowerDensity = (powerTxW / (txBandwidthConfiguration * 180000));
338  }
339  else
340  {
341  txPowerDensity = (basicPowerTxW / (txBandwidthConfiguration * 180000));
342  }
343 
344  (*txPsd)[rbId] = txPowerDensity;
345  }
346 
347  NS_LOG_LOGIC(*txPsd);
348 
349  return txPsd;
350 }
351 
354  uint16_t txBandwidthConfiguration,
355  double powerTx,
356  std::vector<int> activeRbs)
357 {
358  NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << powerTx << activeRbs);
359 
360  Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
361  Ptr<SpectrumValue> txPsd = Create<SpectrumValue>(model);
362 
363  // powerTx is expressed in dBm. We must convert it into natural unit.
364  double powerTxW = std::pow(10., (powerTx - 30) / 10);
365 
366  double txPowerDensity = (powerTxW / (activeRbs.size() * 180000));
367 
368  for (auto it = activeRbs.begin(); it != activeRbs.end(); it++)
369  {
370  int rbId = (*it);
371  (*txPsd)[rbId] = txPowerDensity;
372  }
373 
374  NS_LOG_LOGIC(*txPsd);
375 
376  return txPsd;
377 }
378 
381  uint16_t txBandwidthConfiguration,
382  double noiseFigure)
383 {
384  NS_LOG_FUNCTION(earfcn << txBandwidthConfiguration << noiseFigure);
385  Ptr<SpectrumModel> model = GetSpectrumModel(earfcn, txBandwidthConfiguration);
386  return CreateNoisePowerSpectralDensity(noiseFigure, model);
387 }
388 
391  Ptr<SpectrumModel> spectrumModel)
392 {
393  NS_LOG_FUNCTION(noiseFigureDb << spectrumModel);
394 
395  // see "LTE - From theory to practice"
396  // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
397  const double kT_dBm_Hz = -174.0; // dBm/Hz
398  double kT_W_Hz = std::pow(10.0, (kT_dBm_Hz - 30) / 10.0);
399  double noiseFigureLinear = std::pow(10.0, noiseFigureDb / 10.0);
400  double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
401 
402  Ptr<SpectrumValue> noisePsd = Create<SpectrumValue>(spectrumModel);
403  (*noisePsd) = noisePowerSpectralDensity;
404  return noisePsd;
405 }
406 
407 } // namespace ns3
double f(double x, void *params)
Definition: 80211b.c:70
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:179
#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.
static const EutraChannelNumbers g_eutraChannelNumbers[]
Eutra channel numbers.
std::vector< BandInfo > Bands
Container of BandInfo.
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
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.