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 (uint8_t transmissionBandwidth)
177 {
178  NS_LOG_FUNCTION ((uint16_t) 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 " << (uint16_t) transmissionBandwidth);
195  }
196 }
197 
198 
199 
200 
203 {
210  LteSpectrumModelId (uint32_t f, uint8_t b);
211  uint32_t earfcn;
212  uint8_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, uint8_t txBandwidthConfiguration)
240 {
241  NS_LOG_FUNCTION (earfcn << (uint16_t) 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, uint8_t txBandwidthConfiguration, double powerTx, std::vector <int> activeRbs)
275 {
276  NS_LOG_FUNCTION (earfcn << (uint16_t) 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, uint8_t txBandwidthConfiguration, double powerTx, std::map<int, double> powerTxMap, std::vector <int> activeRbs)
299 {
300  NS_LOG_FUNCTION (earfcn << (uint16_t) 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 
335 
336 
338 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t earfcn, uint8_t txBandwidthConfiguration, double noiseFigure)
339 {
340  NS_LOG_FUNCTION (earfcn << (uint16_t) txBandwidthConfiguration << noiseFigure);
341  Ptr<SpectrumModel> model = GetSpectrumModel (earfcn, txBandwidthConfiguration);
342  return CreateNoisePowerSpectralDensity (noiseFigure, model);
343 }
344 
347 {
348  NS_LOG_FUNCTION (noiseFigureDb << spectrumModel);
349 
350 
351  // see "LTE - From theory to practice"
352  // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
353  const double kT_dBm_Hz = -174.0; // dBm/Hz
354  double kT_W_Hz = std::pow (10.0, (kT_dBm_Hz - 30) / 10.0);
355  double noiseFigureLinear = std::pow (10.0, noiseFigureDb / 10.0);
356  double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
357 
358  Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (spectrumModel);
359  (*noisePsd) = noisePowerSpectralDensity;
360  return noisePsd;
361 }
362 
363 } // namespace ns3
#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:202
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
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:153
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint8_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
uint32_t nOffsUl
number offset UL
static std::map< LteSpectrumModelId, Ptr< SpectrumModel > > g_lteSpectrumModelMap
LTE spectrum model map.
LteSpectrumModelId structure.
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint32_t earfcn, uint8_t bandwidth, double powerTx, std::vector< int > activeRbs)
create a spectrum value representing the power spectral density of a signal to be transmitted...
double fc
center frequency
static Ptr< SpectrumModel > GetSpectrumModel(uint32_t earfcn, uint8_t bandwidth)
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 double GetChannelBandwidth(uint8_t txBandwidthConf)
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 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:254
double fh
upper limit of subband
The building block of a SpectrumModel.
uint32_t nOffsDl
number offset DL
static uint16_t GetUplinkCarrierBand(uint32_t nUl)
Converts uplink EARFCN to corresponding LTE frequency band number.