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 powerTxW = std::pow (10., (powerTx - 30) / 10);
307  double basicPowerTxW = std::pow (10., (powerTx - 30) / 10);
308 
309 
310  for (std::vector <int>::iterator it = activeRbs.begin (); it != activeRbs.end (); it++)
311  {
312  int rbId = (*it);
313 
314  std::map<int, double>::iterator powerIt = powerTxMap.find (rbId);
315 
316  double txPowerDensity;
317 
318  if (powerIt != powerTxMap.end ())
319  {
320  powerTxW = std::pow (10., (powerIt->second - 30) / 10);
321  txPowerDensity = (powerTxW / (txBandwidthConfiguration * 180000));
322  }
323  else
324  {
325  txPowerDensity = (basicPowerTxW / (txBandwidthConfiguration * 180000));
326  }
327 
328  (*txPsd)[rbId] = txPowerDensity;
329  }
330 
331  NS_LOG_LOGIC (*txPsd);
332 
333  return txPsd;
334 }
335 
336 
337 
339 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint32_t earfcn, uint8_t txBandwidthConfiguration, double noiseFigure)
340 {
341  NS_LOG_FUNCTION (earfcn << (uint16_t) txBandwidthConfiguration << noiseFigure);
342  Ptr<SpectrumModel> model = GetSpectrumModel (earfcn, txBandwidthConfiguration);
343  return CreateNoisePowerSpectralDensity (noiseFigure, model);
344 }
345 
348 {
349  NS_LOG_FUNCTION (noiseFigureDb << spectrumModel);
350 
351 
352  // see "LTE - From theory to practice"
353  // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
354  const double kT_dBm_Hz = -174.0; // dBm/Hz
355  double kT_W_Hz = std::pow (10.0, (kT_dBm_Hz - 30) / 10.0);
356  double noiseFigureLinear = std::pow (10.0, noiseFigureDb / 10.0);
357  double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
358 
359  Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (spectrumModel);
360  (*noisePsd) = noisePowerSpectralDensity;
361  return noisePsd;
362 }
363 
364 } // namespace ns3
#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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
#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.
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.
SpectrumModelUid_t GetUid() const
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:72
static uint16_t GetUplinkCarrierBand(uint32_t nDl)
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.
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")
#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:90
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:253
double fh
upper limit of subband
The building block of a SpectrumModel.
uint32_t nOffsDl
number offset DL