A Discrete-Event Network Simulator
API
lte-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) 2010 TELEMATICS LAB, DEE - Politecnico di Bari
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Giuseppe Piro <g.piro@poliba.it>
19  * Nicola Baldo <nbaldo@cttc.es>
20  */
21 
22 #include <map>
23 #include <cmath>
24 
25 #include <ns3/log.h>
26 #include <ns3/fatal-error.h>
27 
29 
30 // just needed to log a std::vector<int> properly...
31 namespace std {
32 
43 ostream&
44 operator << (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 }
57 
58 namespace ns3 {
59 
60 NS_LOG_COMPONENT_DEFINE ("LteSpectrumValueHelper");
61 
67 static const struct EutraChannelNumbers
68 {
69  uint8_t band;
70  double fDlLow;
71  uint32_t nOffsDl;
72  uint32_t rangeNdl1;
73  uint32_t rangeNdl2;
74  double fUlLow;
75  uint32_t nOffsUl;
76  uint32_t rangeNul1;
77  uint32_t rangeNul2;
79  { 1, 2110, 0, 0, 599, 1920, 18000, 18000, 18599},
80  { 2, 1930, 600, 600, 1199, 1850, 18600, 18600, 19199},
81  { 3, 1805, 1200, 1200, 1949, 1710, 19200, 19200, 19949},
82  { 4, 2110, 1950, 1950, 2399, 1710, 19950, 19950, 20399},
83  { 5, 869, 2400, 2400, 2649, 824, 20400, 20400, 20649},
84  { 6, 875, 2650, 2650, 2749, 830, 20650, 20650, 20749},
85  { 7, 2620, 2750, 2750, 3449, 2500, 20750, 20750, 21449},
86  { 8, 925, 3450, 3450, 3799, 880, 21450, 21450, 21799},
87  { 9, 1844.9, 3800, 3800, 4149, 1749.9, 21800, 21800, 22149},
88  { 10, 2110, 4150, 4150, 4749, 1710, 22150, 22150, 22749},
89  { 11, 1475.9, 4750, 4750, 4949, 1427.9, 22750, 22750, 22949},
90  { 12, 728, 5000, 5000, 5179, 698, 23000, 23000, 23179},
91  { 13, 746, 5180, 5180, 5279, 777, 23180, 23180, 23279},
92  { 14, 758, 5280, 5280, 5379, 788, 23280, 23280, 23379},
93  { 17, 734, 5730, 5730, 5849, 704, 23730, 23730, 23849},
94  { 18, 860, 5850, 5850, 5999, 815, 23850, 23850, 23999},
95  { 19, 875, 6000, 6000, 6149, 830, 24000, 24000, 24149},
96  { 20, 791, 6150, 6150, 6449, 832, 24150, 24150, 24449},
97  { 21, 1495.9, 6450, 6450, 6599, 1447.9, 24450, 24450, 24599},
98  { 33, 1900, 36000, 36000, 36199, 1900, 36000, 36000, 36199},
99  { 34, 2010, 36200, 36200, 36349, 2010, 36200, 36200, 36349},
100  { 35, 1850, 36350, 36350, 36949, 1850, 36350, 36350, 36949},
101  { 36, 1930, 36950, 36950, 37549, 1930, 36950, 36950, 37549},
102  { 37, 1910, 37550, 37550, 37749, 1910, 37550, 37550, 37749},
103  { 38, 2570, 37750, 37750, 38249, 2570, 37750, 37750, 38249},
104  { 39, 1880, 38250, 38250, 38649, 1880, 38250, 38250, 38649},
105  { 40, 2300, 38650, 38650, 39649, 2300, 38650, 38650, 39649}
106 };
107 
109 #define NUM_EUTRA_BANDS (sizeof (g_eutraChannelNumbers) / sizeof (EutraChannelNumbers))
110 
111 double
113 {
114  NS_LOG_FUNCTION (earfcn);
115  if (earfcn < 7000)
116  {
117  // FDD downlink
118  return GetDownlinkCarrierFrequency (earfcn);
119  }
120  else
121  {
122  // either FDD uplink or TDD (for which uplink & downlink have same frequency)
123  return GetUplinkCarrierFrequency (earfcn);
124  }
125 }
126 
127 uint16_t
129 {
130  NS_LOG_FUNCTION (nDl);
131  for (uint16_t i = 0; i < NUM_EUTRA_BANDS; ++i)
132  {
133  if (g_eutraChannelNumbers[i].rangeNdl1 <= nDl &&
134  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 
144 uint16_t
146 {
147  NS_LOG_FUNCTION (nUl);
148  for (uint16_t i = 0; i < NUM_EUTRA_BANDS; ++i)
149  {
150  if (g_eutraChannelNumbers[i].rangeNul1 <= nUl &&
151  g_eutraChannelNumbers[i].rangeNul2 >= nUl)
152  {
153  NS_LOG_LOGIC ("entry " << i << " fUlLow=" << g_eutraChannelNumbers[i].fUlLow);
154  return i;
155  }
156  }
157  NS_LOG_ERROR ("invalid EARFCN " << nUl);
158  return NUM_EUTRA_BANDS;
159 }
160 
161 double
163 {
164  NS_LOG_FUNCTION (nDl);
165  uint16_t i = GetDownlinkCarrierBand (nDl);
166  if (i == NUM_EUTRA_BANDS)
167  {
168  return 0.0;
169  }
170  return 1.0e6 * (g_eutraChannelNumbers[i].fDlLow + 0.1 * (nDl - g_eutraChannelNumbers[i].nOffsDl));
171 }
172 
173 double
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 * (g_eutraChannelNumbers[i].fUlLow + 0.1 * (nUl - g_eutraChannelNumbers[i].nOffsUl));
183 }
184 
185 double
186 LteSpectrumValueHelper::GetChannelBandwidth (uint16_t transmissionBandwidth)
187 {
188  NS_LOG_FUNCTION (transmissionBandwidth);
189  switch (transmissionBandwidth)
190  {
191  case 6:
192  return 1.4e6;
193  case 15:
194  return 3.0e6;
195  case 25:
196  return 5.0e6;
197  case 50:
198  return 10.0e6;
199  case 75:
200  return 15.0e6;
201  case 100:
202  return 20.0e6;
203  default:
204  NS_FATAL_ERROR ("invalid bandwidth value " << transmissionBandwidth);
205  }
206 }
207 
208 
209 
210 
213 {
220  LteSpectrumModelId (uint32_t f, uint8_t b);
221  uint32_t earfcn;
222  uint16_t bandwidth;
223 };
224 
226  : earfcn (f),
227  bandwidth (b)
228 {
229 }
230 
238 bool
240 {
241  return ( (a.earfcn < b.earfcn) || ( (a.earfcn == b.earfcn) && (a.bandwidth < b.bandwidth) ) );
242 }
243 
244 
245 static std::map<LteSpectrumModelId, Ptr<SpectrumModel> > g_lteSpectrumModelMap;
246 
247 
249 LteSpectrumValueHelper::GetSpectrumModel (uint32_t earfcn, uint16_t txBandwidthConfiguration)
250 {
251  NS_LOG_FUNCTION (earfcn << txBandwidthConfiguration);
252  Ptr<SpectrumModel> ret;
253  LteSpectrumModelId key (earfcn, txBandwidthConfiguration);
254  std::map<LteSpectrumModelId, Ptr<SpectrumModel> >::iterator it = g_lteSpectrumModelMap.find (key);
255  if (it != g_lteSpectrumModelMap.end ())
256  {
257  ret = it->second;
258  }
259  else
260  {
261  double fc = GetCarrierFrequency (earfcn);
262  NS_ASSERT_MSG (fc != 0, "invalid EARFCN=" << earfcn);
263 
264  double f = fc - (txBandwidthConfiguration * 180e3 / 2.0);
265  Bands rbs;
266  for (uint8_t numrb = 0; numrb < txBandwidthConfiguration; ++numrb)
267  {
268  BandInfo rb;
269  rb.fl = f;
270  f += 90e3;
271  rb.fc = f;
272  f += 90e3;
273  rb.fh = f;
274  rbs.push_back (rb);
275  }
276  ret = Create<SpectrumModel> (rbs);
277  g_lteSpectrumModelMap.insert (std::pair<LteSpectrumModelId, Ptr<SpectrumModel> > (key, ret));
278  }
279  NS_LOG_LOGIC ("returning SpectrumModel::GetUid () == " << ret->GetUid ());
280  return ret;
281 }
282 
284 LteSpectrumValueHelper::CreateTxPowerSpectralDensity (uint32_t earfcn, uint16_t txBandwidthConfiguration, double powerTx, 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 
308 LteSpectrumValueHelper::CreateTxPowerSpectralDensity (uint32_t earfcn, uint16_t txBandwidthConfiguration, double powerTx, std::map<int, double> powerTxMap, std::vector <int> activeRbs)
309 {
310  NS_LOG_FUNCTION (earfcn << txBandwidthConfiguration << activeRbs);
311 
312  Ptr<SpectrumModel> model = GetSpectrumModel (earfcn, txBandwidthConfiguration);
313  Ptr<SpectrumValue> txPsd = Create <SpectrumValue> (model);
314 
315  // powerTx is expressed in dBm. We must convert it into natural unit.
316  double basicPowerTxW = std::pow (10., (powerTx - 30) / 10);
317 
318 
319  for (std::vector <int>::iterator it = activeRbs.begin (); it != activeRbs.end (); it++)
320  {
321  int rbId = (*it);
322 
323  std::map<int, double>::iterator powerIt = powerTxMap.find (rbId);
324 
325  double txPowerDensity;
326 
327  if (powerIt != powerTxMap.end ())
328  {
329  double powerTxW = std::pow (10., (powerIt->second - 30) / 10);
330  txPowerDensity = (powerTxW / (txBandwidthConfiguration * 180000));
331  }
332  else
333  {
334  txPowerDensity = (basicPowerTxW / (txBandwidthConfiguration * 180000));
335  }
336 
337  (*txPsd)[rbId] = txPowerDensity;
338  }
339 
340  NS_LOG_LOGIC (*txPsd);
341 
342  return txPsd;
343 }
344 
346 LteSpectrumValueHelper::CreateUlTxPowerSpectralDensity (uint16_t earfcn, uint16_t txBandwidthConfiguration, double powerTx, std::vector <int> activeRbs)
347 {
348  NS_LOG_FUNCTION (earfcn << txBandwidthConfiguration << powerTx << activeRbs);
349 
350  Ptr<SpectrumModel> model = GetSpectrumModel (earfcn, txBandwidthConfiguration);
351  Ptr<SpectrumValue> txPsd = Create <SpectrumValue> (model);
352 
353  // powerTx is expressed in dBm. We must convert it into natural unit.
354  double powerTxW = std::pow (10., (powerTx - 30) / 10);
355 
356  double txPowerDensity = (powerTxW / (activeRbs.size() * 180000));
357 
358  for (std::vector <int>::iterator it = activeRbs.begin (); it != activeRbs.end (); it++)
359  {
360  int rbId = (*it);
361  (*txPsd)[rbId] = txPowerDensity;
362  }
363 
364  NS_LOG_LOGIC (*txPsd);
365 
366  return txPsd;
367 }
368 
370 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t earfcn, uint16_t txBandwidthConfiguration, double noiseFigure)
371 {
372  NS_LOG_FUNCTION (earfcn << txBandwidthConfiguration << noiseFigure);
373  Ptr<SpectrumModel> model = GetSpectrumModel (earfcn, txBandwidthConfiguration);
374  return CreateNoisePowerSpectralDensity (noiseFigure, model);
375 }
376 
379 {
380  NS_LOG_FUNCTION (noiseFigureDb << spectrumModel);
381 
382 
383  // see "LTE - From theory to practice"
384  // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
385  const double kT_dBm_Hz = -174.0; // dBm/Hz
386  double kT_W_Hz = std::pow (10.0, (kT_dBm_Hz - 30) / 10.0);
387  double noiseFigureLinear = std::pow (10.0, noiseFigureDb / 10.0);
388  double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
389 
390  Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (spectrumModel);
391  (*noisePsd) = noisePowerSpectralDensity;
392  return noisePsd;
393 }
394 
395 } // 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:88
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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 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:176
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.