A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("LteSpectrumValueHelper");
31 
32 namespace ns3 {
33 
40 {
41  uint8_t band;
42  double fDlLow;
43  uint16_t nOffsDl;
44  uint16_t rangeNdl1;
45  uint16_t rangeNdl2;
46  double fUlLow;
47  uint16_t nOffsUl;
48  uint16_t rangeNul1;
49  uint16_t rangeNul2;
51  { 1, 2110, 0, 0, 599, 1920, 18000, 18000, 18599},
52  { 2, 1930, 600, 600, 1199, 1850, 18600, 18600, 19199},
53  { 3, 1805, 1200, 1200, 1949, 1710, 19200, 19200, 19949},
54  { 4, 2110, 1950, 1950, 2399, 1710, 19950, 19950, 20399},
55  { 5, 869, 2400, 2400, 2649, 824, 20400, 20400, 20649},
56  { 6, 875, 2650, 2650, 2749, 830, 20650, 20650, 20749},
57  { 7, 2620, 2750, 2750, 3449, 2500, 20750, 20750, 21449},
58  { 8, 925, 3450, 3450, 3799, 880, 21450, 21450, 21799},
59  { 9, 1844.9, 3800, 3800, 4149, 1749.9, 21800, 21800, 22149},
60  { 10, 2110, 4150, 4150, 4749, 1710, 22150, 22150, 22749},
61  { 11, 1475.9, 4750, 4750, 4949, 1427.9, 22750, 22750, 22949},
62  { 12, 728, 5000, 5000, 5179, 698, 23000, 23000, 23179},
63  { 13, 746, 5180, 5180, 5279, 777, 23180, 23180, 23279},
64  { 14, 758, 5280, 5280, 5379, 788, 23280, 23280, 23379},
65  { 17, 734, 5730, 5730, 5849, 704, 23730, 23730, 23849},
66  { 18, 860, 5850, 5850, 5999, 815, 23850, 23850, 23999},
67  { 19, 875, 6000, 6000, 6149, 830, 24000, 24000, 24149},
68  { 20, 791, 6150, 6150, 6449, 832, 24150, 24150, 24449},
69  { 21, 1495.9, 6450, 6450, 6599, 1447.9, 24450, 24450, 24599},
70  { 33, 1900, 36000, 36000, 36199, 1900, 36000, 36000, 36199},
71  { 34, 2010, 36200, 36200, 36349, 2010, 36200, 36200, 36349},
72  { 35, 1850, 36350, 36350, 36949, 1850, 36350, 36350, 36949},
73  { 36, 1930, 36950, 36950, 37549, 1930, 36950, 36950, 37549},
74  { 37, 1910, 37550, 37550, 37749, 1910, 37550, 37550, 37749},
75  { 38, 2570, 37750, 37750, 38249, 2570, 37750, 37750, 38249},
76  { 39, 1880, 38250, 38250, 38649, 1880, 38250, 38250, 38649},
77  { 40, 2300, 38650, 38650, 39649, 2300, 38650, 38650, 39649}
78 };
79 
80 #define NUM_EUTRA_BANDS (sizeof (g_eutraChannelNumbers) / sizeof (EutraChannelNumbers))
81 
82 double
84 {
85  NS_LOG_FUNCTION (earfcn);
86  if (earfcn < 7000)
87  {
88  // FDD downlink
89  return GetDownlinkCarrierFrequency (earfcn);
90  }
91  else
92  {
93  // either FDD uplink or TDD (for which uplink & downlink have same frequency)
94  return GetUplinkCarrierFrequency (earfcn);
95  }
96 }
97 
98 double
100 {
101  NS_LOG_FUNCTION (nDl);
102  for (uint16_t i = 0; i < NUM_EUTRA_BANDS; ++i)
103  {
104  if ((g_eutraChannelNumbers[i].rangeNdl1 <= nDl)
105  && (g_eutraChannelNumbers[i].rangeNdl2 >= nDl))
106  {
107  NS_LOG_LOGIC ("entry " << i << " fDlLow=" << g_eutraChannelNumbers[i].fDlLow);
108  return 1.0e6 * (g_eutraChannelNumbers[i].fDlLow + 0.1 * (nDl - g_eutraChannelNumbers[i].nOffsDl));
109  }
110  }
111  NS_LOG_ERROR ("invalid EARFCN " << nDl);
112  return 0.0;
113 }
114 
115 double
117 {
118  NS_LOG_FUNCTION (nUl);
119  for (uint16_t i = 0; i < NUM_EUTRA_BANDS; ++i)
120  {
121  if ((g_eutraChannelNumbers[i].rangeNul1 <= nUl)
122  && (g_eutraChannelNumbers[i].rangeNul2 >= nUl))
123  {
124  NS_LOG_LOGIC ("entry " << i << " fUlLow=" << g_eutraChannelNumbers[i].fUlLow);
125  return 1.0e6 * (g_eutraChannelNumbers[i].fUlLow + 0.1 * (nUl - g_eutraChannelNumbers[i].nOffsUl));
126  }
127  }
128  NS_LOG_ERROR ("invalid EARFCN " << nUl);
129  return 0.0;
130 }
131 
132 double
133 LteSpectrumValueHelper::GetChannelBandwidth (uint8_t transmissionBandwidth)
134 {
135  NS_LOG_FUNCTION ((uint16_t) transmissionBandwidth);
136  switch (transmissionBandwidth)
137  {
138  case 6:
139  return 1.4e6;
140  case 15:
141  return 3.0e6;
142  case 25:
143  return 5.0e6;
144  case 50:
145  return 10.0e6;
146  case 75:
147  return 15.0e6;
148  case 100:
149  return 20.0e6;
150  default:
151  NS_FATAL_ERROR ("invalid bandwidth value " << (uint16_t) transmissionBandwidth);
152  }
153 }
154 
155 
156 
157 
159 {
160  LteSpectrumModelId (uint16_t f, uint8_t b);
161  uint16_t earfcn;
162  uint8_t bandwidth;
163 };
164 
166  : earfcn (f),
167  bandwidth (b)
168 {
169 }
170 
171 bool
173 {
174  return ( (a.earfcn < b.earfcn) || ( (a.earfcn == b.earfcn) && (a.bandwidth < b.bandwidth) ) );
175 }
176 
177 
178 static std::map<LteSpectrumModelId, Ptr<SpectrumModel> > g_lteSpectrumModelMap;
179 
180 
182 LteSpectrumValueHelper::GetSpectrumModel (uint16_t earfcn, uint8_t txBandwidthConfiguration)
183 {
184  NS_LOG_FUNCTION (earfcn << (uint16_t) txBandwidthConfiguration);
185  Ptr<SpectrumModel> ret;
186  LteSpectrumModelId key (earfcn, txBandwidthConfiguration);
187  std::map<LteSpectrumModelId, Ptr<SpectrumModel> >::iterator it = g_lteSpectrumModelMap.find (key);
188  if (it != g_lteSpectrumModelMap.end ())
189  {
190  ret = it->second;
191  }
192  else
193  {
194  double fc = GetCarrierFrequency (earfcn);
195  NS_ASSERT_MSG (fc != 0, "invalid EARFCN=" << earfcn);
196 
197  double f = fc - (txBandwidthConfiguration * 180e3 / 2.0);
198  Bands rbs;
199  for (uint8_t numrb = 0; numrb < txBandwidthConfiguration; ++numrb)
200  {
201  BandInfo rb;
202  rb.fl = f;
203  f += 90e3;
204  rb.fc = f;
205  f += 90e3;
206  rb.fh = f;
207  rbs.push_back (rb);
208  }
209  ret = Create<SpectrumModel> (rbs);
210  g_lteSpectrumModelMap.insert (std::pair<LteSpectrumModelId, Ptr<SpectrumModel> > (key, ret));
211  }
212  NS_LOG_LOGIC ("returning SpectrumModel::GetUid () == " << ret->GetUid ());
213  return ret;
214 }
215 
216 // just needed to log a std::vector<int> properly...
217 std::ostream&
218 operator << (std::ostream& os, const std::vector<int>& v)
219 {
220  std::vector<int>::const_iterator it = v.begin ();
221  while (it != v.end ())
222  {
223  os << *it << " " ;
224  ++it;
225  }
226  os << std::endl;
227  return os;
228 }
229 
230 
231 Ptr<SpectrumValue>
232 LteSpectrumValueHelper::CreateTxPowerSpectralDensity (uint16_t earfcn, uint8_t txBandwidthConfiguration, double powerTx, std::vector <int> activeRbs)
233 {
234  NS_LOG_FUNCTION (earfcn << (uint16_t) txBandwidthConfiguration << powerTx << activeRbs);
235 
236  Ptr<SpectrumModel> model = GetSpectrumModel (earfcn, txBandwidthConfiguration);
237  Ptr<SpectrumValue> txPsd = Create <SpectrumValue> (model);
238 
239  // powerTx is expressed in dBm. We must convert it into natural unit.
240  double powerTxW = pow (10., (powerTx - 30) / 10);
241 
242  double txPowerDensity = (powerTxW / (txBandwidthConfiguration * 180000));
243 
244  for (std::vector <int>::iterator it = activeRbs.begin (); it != activeRbs.end (); it++)
245  {
246  int rbId = (*it);
247  (*txPsd)[rbId] = txPowerDensity;
248  }
249 
250  NS_LOG_LOGIC (*txPsd);
251 
252  return txPsd;
253 }
254 
255 
257 LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (uint16_t earfcn, uint8_t txBandwidthConfiguration, double noiseFigure)
258 {
259  NS_LOG_FUNCTION (earfcn << (uint16_t) txBandwidthConfiguration << noiseFigure);
260  Ptr<SpectrumModel> model = GetSpectrumModel (earfcn, txBandwidthConfiguration);
261  return CreateNoisePowerSpectralDensity (noiseFigure, model);
262 }
263 
266 {
267  NS_LOG_FUNCTION (noiseFigureDb << spectrumModel);
268 
269 
270  // see "LTE - From theory to practice"
271  // Section 22.4.4.2 Thermal Noise and Receiver Noise Figure
272  const double kT_dBm_Hz = -174.0; // dBm/Hz
273  double kT_W_Hz = pow (10.0, (kT_dBm_Hz - 30) / 10.0);
274  double noiseFigureLinear = pow (10.0, noiseFigureDb / 10.0);
275  double noisePowerSpectralDensity = kT_W_Hz * noiseFigureLinear;
276 
277  Ptr<SpectrumValue> noisePsd = Create <SpectrumValue> (spectrumModel);
278  (*noisePsd) = noisePowerSpectralDensity;
279  return noisePsd;
280 }
281 
282 } // namespace ns3