EARFCN calculation
This commit is contained in:
@@ -16,14 +16,119 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Giuseppe Piro <g.piro@poliba.it>
|
||||
* Nicola Baldo <nbaldo@cttc.es>
|
||||
*/
|
||||
|
||||
|
||||
#include "lte-spectrum-value-helper.h"
|
||||
#include <ns3/log.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "lte-spectrum-value-helper.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LteSpectrumValueHelper");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* Table 5.7.3-1 "E-UTRA channel numbers" from 3GPP TS 36.101
|
||||
* The table was converted to C syntax doing a cut & paste from TS 36.101 and running the following filter:
|
||||
* awk '{if ((NR % 7) == 1) printf("{"); printf ("%s",$0); if ((NR % 7) == 0) printf("},\n"); else printf(", ");}' | sed 's/ – /, /g'
|
||||
*/
|
||||
struct EutraChannelNumbers
|
||||
{
|
||||
uint8_t band;
|
||||
double fDlLow;
|
||||
uint16_t nOffsDl;
|
||||
uint16_t rangeNdl1;
|
||||
uint16_t rangeNdl2;
|
||||
double fUlLow;
|
||||
uint16_t nOffsUl;
|
||||
uint16_t rangeNul1;
|
||||
uint16_t rangeNul2;
|
||||
} g_eutraChannelNumbers[] = {
|
||||
{1, 2110, 0, 0, 599, 1920, 18000, 18000, 18599},
|
||||
{2, 1930, 600, 600, 1199, 1850, 18600, 18600, 19199},
|
||||
{3, 1805, 1200, 1200, 1949, 1710, 19200, 19200, 19949},
|
||||
{4, 2110, 1950, 1950, 2399, 1710, 19950, 19950, 20399},
|
||||
{5, 869, 2400, 2400, 2649, 824, 20400, 20400, 20649},
|
||||
{6, 875, 2650, 2650, 2749, 830, 20650, 20650, 20749},
|
||||
{7, 2620, 2750, 2750, 3449, 2500, 20750, 20750, 21449},
|
||||
{8, 925, 3450, 3450, 3799, 880, 21450, 21450, 21799},
|
||||
{9, 1844.9, 3800, 3800, 4149, 1749.9, 21800, 21800, 22149},
|
||||
{10, 2110, 4150, 4150, 4749, 1710, 22150, 22150, 22749},
|
||||
{11, 1475.9, 4750, 4750, 4949, 1427.9, 22750, 22750, 22949},
|
||||
{12, 728, 5000, 5000, 5179, 698, 23000, 23000, 23179},
|
||||
{13, 746, 5180, 5180, 5279, 777, 23180, 23180, 23279},
|
||||
{14, 758, 5280, 5280, 5379, 788, 23280, 23280, 23379},
|
||||
{17, 734, 5730, 5730, 5849, 704, 23730, 23730, 23849},
|
||||
{18, 860, 5850, 5850, 5999, 815, 23850, 23850, 23999},
|
||||
{19, 875, 6000, 6000, 6149, 830, 24000, 24000, 24149},
|
||||
{20, 791, 6150, 6150, 6449, 832, 24150, 24150 - 24449},
|
||||
{21, 1495.9, 6450, 6450, 6599, 1447.9, 24450, 24450, 24599},
|
||||
{33, 1900, 36000, 36000, 36199, 1900, 36000, 36000, 36199},
|
||||
{34, 2010, 36200, 36200, 36349, 2010, 36200, 36200, 36349},
|
||||
{35, 1850, 36350, 36350, 36949, 1850, 36350, 36350, 36949},
|
||||
{36, 1930, 36950, 36950, 37549, 1930, 36950, 36950, 37549},
|
||||
{37, 1910, 37550, 37550, 37749, 1910, 37550, 37550, 37749},
|
||||
{38, 2570, 37750, 37750, 38249, 2570, 37750, 37750, 38249},
|
||||
{39, 1880, 38250, 38250, 38649, 1880, 38250, 38250, 38649},
|
||||
{40, 2300, 38650, 38650, 39649, 2300, 38650, 38650, 39649}
|
||||
};
|
||||
|
||||
#define NUM_EUTRA_BANDS (sizeof (g_eutraChannelNumbers) / sizeof (EutraChannelNumbers))
|
||||
|
||||
double
|
||||
LteSpectrumValueHelper::GetCarrierFrequency (uint16_t earfcn)
|
||||
{
|
||||
NS_LOG_FUNCTION (earfcn);
|
||||
if (earfcn < 7000)
|
||||
{
|
||||
// FDD downlink
|
||||
return GetDownlinkCarrierFrequency (earfcn);
|
||||
}
|
||||
else
|
||||
{
|
||||
// either FDD uplink or TDD (for which uplink & downlink have same frequency)
|
||||
return GetUplinkCarrierFrequency (earfcn);
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
LteSpectrumValueHelper::GetDownlinkCarrierFrequency (uint16_t nDl)
|
||||
{
|
||||
NS_LOG_FUNCTION (nDl);
|
||||
for (uint16_t i = 0; i < NUM_EUTRA_BANDS; ++i)
|
||||
{
|
||||
if ((g_eutraChannelNumbers[i].rangeNdl1 <= nDl) &&
|
||||
(g_eutraChannelNumbers[i].rangeNdl2 >= nDl))
|
||||
{
|
||||
NS_LOG_LOGIC ("entry " << i << " fDlLow=" << g_eutraChannelNumbers[i].fDlLow);
|
||||
return g_eutraChannelNumbers[i].fDlLow + 0.1 * (nDl - g_eutraChannelNumbers[i].nOffsDl);
|
||||
}
|
||||
}
|
||||
NS_LOG_ERROR ("invalid EARFCN " << nDl);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double
|
||||
LteSpectrumValueHelper::GetUplinkCarrierFrequency (uint16_t nUl)
|
||||
{
|
||||
NS_LOG_FUNCTION (nUl);
|
||||
for (uint16_t i = 0; i < NUM_EUTRA_BANDS; ++i)
|
||||
{
|
||||
if ((g_eutraChannelNumbers[i].rangeNul1 <= nUl) &&
|
||||
(g_eutraChannelNumbers[i].rangeNul2 >= nUl))
|
||||
{
|
||||
NS_LOG_LOGIC ("entry " << i << " fUlLow=" << g_eutraChannelNumbers[i].fUlLow);
|
||||
return g_eutraChannelNumbers[i].fUlLow + 0.1 * (nUl - g_eutraChannelNumbers[i].nOffsUl);
|
||||
}
|
||||
}
|
||||
NS_LOG_ERROR ("invalid EARFCN " << nUl);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Ptr<SpectrumModel> LteDownlinkSpectrumModel;
|
||||
Ptr<SpectrumModel> LteUplinkSpectrumModel;
|
||||
|
||||
|
||||
@@ -34,6 +34,41 @@ namespace ns3 {
|
||||
class LteSpectrumValueHelper
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the carrier frequency from the E-UTRA Absolute
|
||||
* Radio Frequency Channel Number (EARFCN) according to 3GPP TS
|
||||
* 36.101 section 5.7.3 "Carrier frequency and EARFCN".
|
||||
*
|
||||
* \param earfcn the EARFCN
|
||||
*
|
||||
* \return the carrier frequency in MHz
|
||||
*/
|
||||
static double GetCarrierFrequency (uint16_t earfcn);
|
||||
|
||||
/**
|
||||
* Calculates the dowlink carrier frequency from the E-UTRA Absolute
|
||||
* Radio Frequency Channel Number (EARFCN) using the formula in 3GPP TS
|
||||
* 36.101 section 5.7.3 "Carrier frequency and EARFCN".
|
||||
*
|
||||
* \param earfcn the EARFCN
|
||||
*
|
||||
* \return the dowlink carrier frequency in MHz
|
||||
*/
|
||||
static double GetDownlinkCarrierFrequency (uint16_t earfcn);
|
||||
|
||||
/**
|
||||
* Calculates the uplink carrier frequency from the E-UTRA Absolute
|
||||
* Radio Frequency Channel Number (EARFCN) using the formula in 3GPP TS
|
||||
* 36.101 section 5.7.3 "Carrier frequency and EARFCN".
|
||||
*
|
||||
* \param earfcn the EARFCN
|
||||
*
|
||||
* \return the uplink carrier frequency in MHz
|
||||
*/
|
||||
static double GetUplinkCarrierFrequency (uint16_t earfcn);
|
||||
|
||||
/**
|
||||
* \brief create spectrum value
|
||||
* \param powerTx the power transmission in dBm
|
||||
|
||||
155
src/lte/test/lte-test-earfcn.cc
Normal file
155
src/lte/test/lte-test-earfcn.cc
Normal file
@@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Nicola Baldo <nbaldo@cttc.es>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
#include "ns3/lte-spectrum-value-helper.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LteTestEarfcn");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class LteEarfcnTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
LteEarfcnTestCase (const char* str, uint16_t earfcn, double f);
|
||||
virtual ~LteEarfcnTestCase ();
|
||||
|
||||
protected:
|
||||
uint16_t m_earfcn;
|
||||
double m_f;
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
};
|
||||
|
||||
LteEarfcnTestCase::LteEarfcnTestCase (const char* str, uint16_t earfcn, double f)
|
||||
: TestCase (str),
|
||||
m_earfcn (earfcn),
|
||||
m_f (f)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << str << earfcn << f);
|
||||
}
|
||||
|
||||
LteEarfcnTestCase::~LteEarfcnTestCase ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LteEarfcnTestCase::DoRun (void)
|
||||
{
|
||||
double f = LteSpectrumValueHelper::GetCarrierFrequency (m_earfcn);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (f, m_f, 0.0000001, "wrong frequency");
|
||||
}
|
||||
|
||||
class LteEarfcnDlTestCase : public LteEarfcnTestCase
|
||||
{
|
||||
public:
|
||||
LteEarfcnDlTestCase (const char* str, uint16_t earfcn, double f);
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
};
|
||||
|
||||
LteEarfcnDlTestCase::LteEarfcnDlTestCase (const char* str, uint16_t earfcn, double f)
|
||||
: LteEarfcnTestCase (str, earfcn, f)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LteEarfcnDlTestCase::DoRun (void)
|
||||
{
|
||||
LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
|
||||
LogComponentEnable ("LteSpectrumValueHelper", logLevel);
|
||||
LogComponentEnable ("LteTestEarfcn", logLevel);
|
||||
|
||||
double f = LteSpectrumValueHelper::GetDownlinkCarrierFrequency (m_earfcn);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (f, m_f, 0.0000001, "wrong frequency");
|
||||
}
|
||||
|
||||
|
||||
class LteEarfcnUlTestCase : public LteEarfcnTestCase
|
||||
{
|
||||
public:
|
||||
LteEarfcnUlTestCase (const char* str, uint16_t earfcn, double f);
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
};
|
||||
|
||||
LteEarfcnUlTestCase::LteEarfcnUlTestCase (const char* str, uint16_t earfcn, double f)
|
||||
: LteEarfcnTestCase (str, earfcn, f)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LteEarfcnUlTestCase::DoRun (void)
|
||||
{
|
||||
double f = LteSpectrumValueHelper::GetUplinkCarrierFrequency (m_earfcn);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (f, m_f, 0.0000001, "wrong frequency");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the calculation of carrier frequency based on EARFCN
|
||||
*/
|
||||
class LteEarfcnTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
LteEarfcnTestSuite ();
|
||||
};
|
||||
|
||||
static LteEarfcnTestSuite g_lteEarfcnTestSuite;
|
||||
|
||||
LteEarfcnTestSuite::LteEarfcnTestSuite ()
|
||||
: TestSuite ("lte-earfcn", SYSTEM)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
AddTestCase (new LteEarfcnDlTestCase ("DL EARFCN=500", 500, 2110+50));
|
||||
AddTestCase (new LteEarfcnDlTestCase ("DL EARFCN=1000", 1000, 1930+(100-60)));
|
||||
AddTestCase (new LteEarfcnDlTestCase ("DL EARFCN=1301", 1301, 1805+(130.1-120)));
|
||||
AddTestCase (new LteEarfcnDlTestCase ("DL EARFCN=7000", 7000, 0.0));
|
||||
AddTestCase (new LteEarfcnDlTestCase ("DL EARFCN=20000", 20000, 0.0));
|
||||
AddTestCase (new LteEarfcnDlTestCase ("DL EARFCN=50000", 50000, 0.0));
|
||||
|
||||
AddTestCase (new LteEarfcnUlTestCase ("UL EARFCN=18100", 18100, 1920 + 1810 - 1800));
|
||||
AddTestCase (new LteEarfcnUlTestCase ("UL EARFCN=19000", 19000, 1850 + 1900 - 1860));
|
||||
AddTestCase (new LteEarfcnUlTestCase ("UL EARFCN=19400", 19400, 1710 + 1940 - 1920));
|
||||
AddTestCase (new LteEarfcnUlTestCase ("UL EARFCN=10", 10, 0.0));
|
||||
AddTestCase (new LteEarfcnUlTestCase ("UL EARFCN=1000", 1000, 0.0));
|
||||
AddTestCase (new LteEarfcnUlTestCase ("UL EARFCN=50000", 50000, 0.0));
|
||||
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=500", 500, 2110+50));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=1000", 1000, 1930+(100-60)));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=1301", 1301, 1805+(130.1-120)));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=8000", 8000, 0.0));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=50000", 50000, 0.0));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=18100", 18100, 1920 + 1810 - 1800));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=19000", 19000, 1850 + 1900 - 1860));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=19400", 19400, 1710 + 1940 - 1920));
|
||||
AddTestCase (new LteEarfcnTestCase ("EARFCN=50000", 50000, 0.0));
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
@@ -51,6 +51,7 @@ def build(bld):
|
||||
'test/lena-test-sinr-chunk-processor.cc',
|
||||
'test/lena-test-rr-ff-mac-scheduler.cc',
|
||||
'test/lena-test-pf-ff-mac-scheduler.cc',
|
||||
'test/lte-test-earfcn.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
|
||||
Reference in New Issue
Block a user