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