lte: (fixes: #2840) Wrong configuration of eNBs and UEs
This commit is contained in:
@@ -57,6 +57,7 @@ Bugs fixed
|
||||
- Bug 2831 - wifi: runtime channel width switch has no effect
|
||||
- Bug 2836 - wifi: Missing VHT information in radiotap header when A-MPDU is used
|
||||
- Bug 2838 - wifi: ht-wifi-network crashes with RTS/CTS enabled and frequency set to 2.4GHz
|
||||
- Bug 2840 - lte: Wrong configuration of eNBs and UEs
|
||||
- Bug 2843 - spectrum, wifi: Incorrect channel width and center frequency provided for non-HT PPDUs when building SpectralDensity
|
||||
- Bug 2848 - wifi: Association ID not correctly set upon association
|
||||
- Bug 2849 - lte: Received RLC and PDCP PDUs are missing in the stats files
|
||||
|
||||
@@ -1601,4 +1601,28 @@ are configured to use the secondary carrier and the component carrier manager is
|
||||
split the data uniformly between primary and secondary carrier. The test consists of checking that
|
||||
the throughput obtained over the different carriers are equal considering a given tolerance. For more
|
||||
details about this test, see the section Carrier aggregation usage example.
|
||||
|
||||
|
||||
|
||||
Carrier aggregation test for eNB and UE configuration
|
||||
------------------------------------------------------
|
||||
|
||||
The test suite ``carrier-aggregation-config-test`` is a system test program, which verifies the
|
||||
following two cases:
|
||||
|
||||
* When carrier aggregation is enabled and UE carriers configuration is different than the default
|
||||
configuration done in LteHelper, we check that the UE(s) is configured properly once it receives
|
||||
RRC Connection Reconfiguration message from eNB.
|
||||
|
||||
* A user can configure 2 or more eNBs and UEs with different configuration parameters, i.e.,
|
||||
each eNB and UE can have different EARFCN and Bandwidths and a UE connects to an eNB with similar DL EARFCN.
|
||||
In this test, we check with CA enabled but the end results will be the same if carrier aggregation is not
|
||||
enabled and we have more than one eNBs and UEs with different configurations.
|
||||
|
||||
Since, we do not need EPC to test the configuration, this test only simulates the LTE radio access with RLC SM.
|
||||
There are two test cases, Test 1 tests that the UE is configured properly after receiving RRC Connection Reconfiguration
|
||||
message from the eNB, which will overwrite UE default configuration done in LteHelper for the sake of
|
||||
creating PHY and MAC instances equal to the number of component carriers. Test 2 tests that every eNB or UE in a
|
||||
simulation scenario can be configured with different EARFCNs and Bandwidths. For both test cases, it also counts
|
||||
the number of times the hooked trace source ``SCarrierConfigured`` get triggered. As, it reflects how many UEs
|
||||
got attached to their respective eNB. If the count is not equal to the number of UEs in the scenario, the test fails,
|
||||
which could be the result of improper UE configuration.
|
||||
|
||||
@@ -513,31 +513,39 @@ LteHelper::InstallUeDevice (NodeContainer c)
|
||||
Ptr<NetDevice>
|
||||
LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << n);
|
||||
uint16_t cellId = m_cellIdCounter; // \todo Remove, eNB has no cell ID
|
||||
|
||||
Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
|
||||
Ptr<LteHandoverAlgorithm> handoverAlgorithm = m_handoverAlgorithmFactory.Create<LteHandoverAlgorithm> ();
|
||||
|
||||
if (m_componentCarrierPhyParams.size() == 0)
|
||||
{
|
||||
DoComponentCarrierConfigure (dev->GetUlEarfcn (), dev->GetDlEarfcn (), dev->GetUlBandwidth (), dev->GetDlBandwidth ());
|
||||
}
|
||||
NS_ABORT_MSG_IF (m_componentCarrierPhyParams.size() != 0, "CC map is not clean");
|
||||
DoComponentCarrierConfigure (dev->GetUlEarfcn (), dev->GetDlEarfcn (),
|
||||
dev->GetUlBandwidth (), dev->GetDlBandwidth ());
|
||||
NS_ABORT_MSG_IF (m_componentCarrierPhyParams.size() != m_noOfCcs,
|
||||
"CC map size (" << m_componentCarrierPhyParams.size () <<
|
||||
") must be equal to number of carriers (" <<
|
||||
m_noOfCcs << ")");
|
||||
|
||||
NS_ASSERT_MSG(m_componentCarrierPhyParams.size()!=0, "Cannot create enb ccm map.");
|
||||
// create component carrier map for this eNb device
|
||||
std::map<uint8_t,Ptr<ComponentCarrierEnb> > ccMap;
|
||||
for (std::map<uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyParams.begin (); it != m_componentCarrierPhyParams.end (); ++it)
|
||||
for (std::map<uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyParams.begin ();
|
||||
it != m_componentCarrierPhyParams.end ();
|
||||
++it)
|
||||
{
|
||||
Ptr <ComponentCarrierEnb> cc = CreateObject<ComponentCarrierEnb> ();
|
||||
cc->SetUlBandwidth(it->second.GetUlBandwidth());
|
||||
cc->SetDlBandwidth(it->second.GetDlBandwidth());
|
||||
cc->SetDlEarfcn(it->second.GetDlEarfcn());
|
||||
cc->SetUlEarfcn(it->second.GetUlEarfcn());
|
||||
cc->SetAsPrimary(it->second.IsPrimary());
|
||||
Ptr <ComponentCarrierEnb> cc = CreateObject<ComponentCarrierEnb> ();
|
||||
cc->SetUlBandwidth (it->second.GetUlBandwidth ());
|
||||
cc->SetDlBandwidth (it->second.GetDlBandwidth ());
|
||||
cc->SetDlEarfcn (it->second.GetDlEarfcn ());
|
||||
cc->SetUlEarfcn (it->second.GetUlEarfcn ());
|
||||
cc->SetAsPrimary (it->second.IsPrimary ());
|
||||
NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num cells exceeded");
|
||||
cc->SetCellId (m_cellIdCounter++);
|
||||
ccMap [it->first] = cc;
|
||||
}
|
||||
// CC map is not needed anymore
|
||||
m_componentCarrierPhyParams.clear ();
|
||||
|
||||
NS_ABORT_MSG_IF (m_useCa && ccMap.size()<2, "You have to either specify carriers or disable carrier aggregation");
|
||||
NS_ASSERT (ccMap.size () == m_noOfCcs);
|
||||
|
||||
@@ -764,24 +772,38 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
NS_ABORT_MSG_IF (m_componentCarrierPhyParams.size() == 0 && m_useCa, "If CA is enabled, before call this method you need to install Enbs --> InstallEnbDevice()");
|
||||
|
||||
Ptr<LteUeNetDevice> dev = m_ueNetDeviceFactory.Create<LteUeNetDevice> ();
|
||||
|
||||
// Initialize the component carriers with default values in order to initialize MACs and PHYs
|
||||
// of each component carrier. These values must be updated once the UE is attached to the
|
||||
// eNB and receives RRC Connection Reconfiguration message. In case of primary carrier or
|
||||
// a single carrier, these values will be updated once the UE will receive SIB2 and MIB.
|
||||
NS_ABORT_MSG_IF (m_componentCarrierPhyParams.size() != 0, "CC map is not clean");
|
||||
DoComponentCarrierConfigure (dev->GetDlEarfcn () + 18000, dev->GetDlEarfcn (), 25, 25);
|
||||
NS_ABORT_MSG_IF (m_componentCarrierPhyParams.size() != m_noOfCcs,
|
||||
"CC map size (" << m_componentCarrierPhyParams.size () <<
|
||||
") must be equal to number of carriers (" <<
|
||||
m_noOfCcs << ")");
|
||||
|
||||
std::map<uint8_t, Ptr<ComponentCarrierUe> > ueCcMap;
|
||||
|
||||
for (std::map< uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyParams.begin() ; it != m_componentCarrierPhyParams.end(); ++it)
|
||||
for (std::map< uint8_t, ComponentCarrier >::iterator it = m_componentCarrierPhyParams.begin();
|
||||
it != m_componentCarrierPhyParams.end();
|
||||
++it)
|
||||
{
|
||||
Ptr <ComponentCarrierUe> cc = CreateObject<ComponentCarrierUe> ();
|
||||
cc->SetUlBandwidth ( it->second.GetUlBandwidth ());
|
||||
cc->SetDlBandwidth ( it->second.GetDlBandwidth ());
|
||||
cc->SetDlEarfcn ( it->second.GetDlEarfcn ());
|
||||
cc->SetUlEarfcn ( it->second.GetUlEarfcn ());
|
||||
cc->SetAsPrimary (it->second.IsPrimary());
|
||||
Ptr <ComponentCarrierUe> cc = CreateObject<ComponentCarrierUe> ();
|
||||
cc->SetUlBandwidth (it->second.GetUlBandwidth ());
|
||||
cc->SetDlBandwidth (it->second.GetDlBandwidth ());
|
||||
cc->SetDlEarfcn (it->second.GetDlEarfcn ());
|
||||
cc->SetUlEarfcn (it->second.GetUlEarfcn ());
|
||||
cc->SetAsPrimary (it->second.IsPrimary ());
|
||||
Ptr<LteUeMac> mac = CreateObject<LteUeMac> ();
|
||||
cc->SetMac (mac);
|
||||
// cc->GetPhy ()->Initialize (); // it is initialized within the LteUeNetDevice::DoInitialize ()
|
||||
ueCcMap.insert (std::pair<uint8_t, Ptr<ComponentCarrierUe> > (it->first, cc));
|
||||
}
|
||||
// CC map is not needed anymore
|
||||
m_componentCarrierPhyParams.clear ();
|
||||
|
||||
for (std::map<uint8_t, Ptr<ComponentCarrierUe> >::iterator it = ueCcMap.begin (); it != ueCcMap.end (); ++it)
|
||||
{
|
||||
@@ -887,10 +909,9 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
|
||||
it->second->GetPhy ()->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser (it->first));
|
||||
rrc->SetLteUeCphySapProvider (it->second->GetPhy ()->GetLteUeCphySapProvider (), it->first);
|
||||
it->second->GetPhy ()->SetComponentCarrierId (it->first);
|
||||
|
||||
it->second->GetPhy ()->SetLteUePhySapUser (it->second->GetMac ()->GetLteUePhySapUser ());
|
||||
it->second->GetMac ()->SetLteUePhySapProvider (it->second->GetPhy ()->GetLteUePhySapProvider ());
|
||||
|
||||
|
||||
bool ccmTest = ccmUe->SetComponentCarrierMacSapProviders (it->first, it->second->GetMac ()->GetLteMacSapProvider());
|
||||
|
||||
if (ccmTest == false)
|
||||
@@ -1282,7 +1303,9 @@ LteHelper::DoDeActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, Ptr<NetDevic
|
||||
void
|
||||
LteHelper::DoComponentCarrierConfigure (uint32_t ulEarfcn, uint32_t dlEarfcn, uint8_t ulbw, uint8_t dlbw)
|
||||
{
|
||||
NS_ASSERT_MSG (m_componentCarrierPhyParams.size()==0, "Cc map already exists.");
|
||||
NS_LOG_FUNCTION (this << ulEarfcn << dlEarfcn << ulbw << dlbw);
|
||||
|
||||
NS_ABORT_MSG_IF (m_componentCarrierPhyParams.size() != 0, "CC map is not clean");
|
||||
Ptr<CcHelper> ccHelper = CreateObject<CcHelper> ();
|
||||
ccHelper->SetNumberOfComponentCarriers (m_noOfCcs);
|
||||
ccHelper->SetUlEarfcn (ulEarfcn);
|
||||
@@ -1290,7 +1313,7 @@ LteHelper::DoComponentCarrierConfigure (uint32_t ulEarfcn, uint32_t dlEarfcn, ui
|
||||
ccHelper->SetDlBandwidth (dlbw);
|
||||
ccHelper->SetUlBandwidth (ulbw);
|
||||
m_componentCarrierPhyParams = ccHelper->EquallySpacedCcs ();
|
||||
m_componentCarrierPhyParams.at(0).SetAsPrimary(true);
|
||||
m_componentCarrierPhyParams.at (0).SetAsPrimary (true);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -685,12 +685,12 @@ protected:
|
||||
private:
|
||||
|
||||
/**
|
||||
* A private function used for component carrier configuration.
|
||||
* Configure the component carriers
|
||||
*
|
||||
* \param ulEarfcn uplink EARFCN - not control on the validity at this point
|
||||
* \param dlEarfcn downlink EARFCN - not control on the validity at this point
|
||||
* \param ulbw uplink bandwidth for the current CC
|
||||
* \param dlbw downlink bandwidth for the current CC
|
||||
* \param ulEarfcn uplink EARFCN
|
||||
* \param dlEarfcn downlink EARFCN
|
||||
* \param ulbw uplink bandwidth for each CC
|
||||
* \param dlbw downlink bandwidth for each CC
|
||||
*/
|
||||
void DoComponentCarrierConfigure (uint32_t ulEarfcn, uint32_t dlEarfcn, uint8_t ulbw, uint8_t dlbw);
|
||||
/**
|
||||
|
||||
@@ -277,6 +277,10 @@ LteUeRrc::GetTypeId (void)
|
||||
"trace fired upon failure of a handover procedure",
|
||||
MakeTraceSourceAccessor (&LteUeRrc::m_handoverEndErrorTrace),
|
||||
"ns3::LteUeRrc::ImsiCidRntiTracedCallback")
|
||||
.AddTraceSource ("SCarrierConfigured",
|
||||
"trace fired after configuring secondary carriers",
|
||||
MakeTraceSourceAccessor (&LteUeRrc::m_sCarrierConfiguredTrace),
|
||||
"ns3::LteUeRrc::SCellConfiguredCallback")
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@@ -1231,6 +1235,8 @@ LteUeRrc::ApplyRadioResourceConfigDedicatedSecondaryCarrier (LteRrcSap::NonCriti
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
m_sCellToAddModList = nonCec.sCellsToAddModList;
|
||||
|
||||
for(std::list<LteRrcSap::SCellToAddMod>::iterator it = nonCec.sCellsToAddModList.begin(); it!=nonCec.sCellsToAddModList.end(); it++)
|
||||
{
|
||||
LteRrcSap::SCellToAddMod scell = *it;
|
||||
@@ -1258,6 +1264,8 @@ LteUeRrc::ApplyRadioResourceConfigDedicatedSecondaryCarrier (LteRrcSap::NonCriti
|
||||
m_cphySapProvider.at (ccId)->SetPa (paDouble);
|
||||
m_cphySapProvider.at (ccId)->SetSrsConfigurationIndex (srsIndex);
|
||||
}
|
||||
|
||||
m_sCarrierConfiguredTrace (this, m_sCellToAddModList);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -352,6 +352,15 @@ public:
|
||||
(uint64_t imsi, uint16_t cellId, uint16_t rnti,
|
||||
State oldState, State newState);
|
||||
|
||||
/**
|
||||
* TracedCallback signature for secondary carrier configuration events.
|
||||
*
|
||||
* \param [in] Pointer to UE RRC
|
||||
* \param [in] List of LteRrcSap::SCellToAddMod
|
||||
*/
|
||||
typedef void (* SCarrierConfiguredCallback)
|
||||
(Ptr<LteUeRrc>, std::list<LteRrcSap::SCellToAddMod>);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -768,6 +777,7 @@ private:
|
||||
|
||||
uint32_t m_dlEarfcn; /**< Downlink carrier frequency. */
|
||||
uint32_t m_ulEarfcn; /**< Uplink carrier frequency. */
|
||||
std::list<LteRrcSap::SCellToAddMod> m_sCellToAddModList; /**< Secondary carriers. */
|
||||
|
||||
/**
|
||||
* The `MibReceived` trace source. Fired upon reception of Master Information
|
||||
@@ -842,6 +852,12 @@ private:
|
||||
* procedure. Exporting IMSI, cell ID, and RNTI.
|
||||
*/
|
||||
TracedCallback<uint64_t, uint16_t, uint16_t> m_handoverEndErrorTrace;
|
||||
/**
|
||||
* The `SCarrierConfigured` trace source. Fired after the configuration
|
||||
* of secondary carriers received through RRC Connection Reconfiguration
|
||||
* message.
|
||||
*/
|
||||
TracedCallback<Ptr<LteUeRrc>, std::list<LteRrcSap::SCellToAddMod> > m_sCarrierConfiguredTrace;
|
||||
|
||||
/// True if a connection request by upper layers is pending.
|
||||
bool m_connectionPending;
|
||||
|
||||
374
src/lte/test/lte-test-carrier-aggregation-configuration.cc
Normal file
374
src/lte/test/lte-test-carrier-aggregation-configuration.cc
Normal file
@@ -0,0 +1,374 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2018 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: Zoraze Ali <zoraze.ali@cttc.es>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ns3/object.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/ptr.h>
|
||||
#include <ns3/constant-position-mobility-model.h>
|
||||
#include <ns3/node-container.h>
|
||||
#include <ns3/mobility-helper.h>
|
||||
#include <ns3/net-device-container.h>
|
||||
#include <ns3/lte-ue-rrc.h>
|
||||
#include <ns3/lte-helper.h>
|
||||
#include <ns3/lte-spectrum-value-helper.h>
|
||||
#include <ns3/callback.h>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
/**
|
||||
* This test suite verifies following two things:
|
||||
*
|
||||
* 1. When CA is enabled and UE carriers configuration is different than the default one,
|
||||
* we check that the UE is configured properly once it receives
|
||||
* RRC Connection Reconfiguration message from eNB.
|
||||
*
|
||||
* 2. A user can configure 2 or more eNBs and UEs with different configuration parameters,
|
||||
* i.e, each eNB and UE can have different EARFCN and Bandwidths and a UE connects to
|
||||
* an eNB with similar DL EARFCN.
|
||||
* Here we check it with CA enabled but the end results will be the same if CA is not
|
||||
* enabled and we have more than one eNBs and UEs with different configurations.
|
||||
*
|
||||
* Since we do not need EPC to test the configuration, this test only simulates
|
||||
* the LTE radio access with RLC SM.
|
||||
*
|
||||
* Test 1 tests that the UE is configured properly after receiving RRC Connection
|
||||
* Reconfiguration message from the eNB, which will overwrite UE default configuration
|
||||
* done in LteHelper for the sake of creating PHY and MAC instances equal to the number
|
||||
* of component carriers.
|
||||
*
|
||||
* Test 2 tests that in a simulation scenario every eNB or UE can be configured with
|
||||
* different EARFCNs and Bandwidths. This will check that the eNBs and UEs configuration
|
||||
* is not static, as reported in BUG 2840.
|
||||
*/
|
||||
|
||||
struct ConfigToCheck
|
||||
{
|
||||
uint16_t m_dlBandwidth;
|
||||
uint16_t m_ulBandwidth;
|
||||
uint32_t m_dlEarfcn;
|
||||
uint32_t m_ulEarfcn;
|
||||
};
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("TestCarrierAggregationConfig");
|
||||
|
||||
class CarrierAggregationConfigTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param numberOfNodes, Total Number of eNBs and UEs
|
||||
* \param configToCheck, Vector containing all the configurations to check
|
||||
* \param simulationDuration, Duration of the simulation
|
||||
*/
|
||||
CarrierAggregationConfigTestCase (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration)
|
||||
: TestCase (BuildNameString (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration)),
|
||||
m_numberOfNodes(numberOfNodes),
|
||||
m_numberOfComponentCarriers(numberOfComponentCarriers),
|
||||
m_configToCheck(configToCheck),
|
||||
m_simulationDuration (simulationDuration)
|
||||
{
|
||||
m_connectionCounter = 0.0;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
|
||||
std::string BuildNameString (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration);
|
||||
void Evaluate (std::string context, Ptr<LteUeRrc> ueRrc, std::list<LteRrcSap::SCellToAddMod> sCellToAddModList);
|
||||
std::vector<std::map<uint16_t, ConfigToCheck> > EquallySpacedCcs ();
|
||||
|
||||
uint32_t m_numberOfNodes;
|
||||
uint16_t m_numberOfComponentCarriers;
|
||||
std::vector<ConfigToCheck> m_configToCheck;
|
||||
uint32_t m_connectionCounter;
|
||||
Time m_simulationDuration;
|
||||
std::vector<std::map<uint16_t, ConfigToCheck> > m_configToCheckContainer;
|
||||
};
|
||||
|
||||
std::string
|
||||
CarrierAggregationConfigTestCase::BuildNameString (uint32_t numberOfNodes, uint16_t numberOfComponentCarriers, std::vector<ConfigToCheck> configToCheck, Time simulationDuration)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << " nodes " << numberOfNodes << " carriers " << numberOfComponentCarriers
|
||||
<< " configurations " << configToCheck.size ()
|
||||
<< " duration " << simulationDuration;
|
||||
return oss.str ();
|
||||
}
|
||||
|
||||
std::vector<std::map<uint16_t, ConfigToCheck> >
|
||||
CarrierAggregationConfigTestCase::EquallySpacedCcs ()
|
||||
{
|
||||
std::vector<std::map<uint16_t, ConfigToCheck> > configToCheckContainer;
|
||||
|
||||
for (auto &it: m_configToCheck)
|
||||
{
|
||||
std::map<uint16_t, ConfigToCheck> ccmap;
|
||||
uint32_t ulEarfcn = it.m_ulEarfcn;
|
||||
uint32_t dlEarfcn = it.m_dlEarfcn;
|
||||
uint32_t maxBandwidthRb = std::max<uint32_t> (it.m_ulBandwidth, it.m_dlBandwidth);
|
||||
|
||||
// Convert bandwidth from RBs to kHz
|
||||
uint32_t maxBandwidthKhz = LteSpectrumValueHelper::GetChannelBandwidth (maxBandwidthRb) / 1e3;
|
||||
|
||||
for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
|
||||
{
|
||||
// Make sure we stay within the same band.
|
||||
if (LteSpectrumValueHelper::GetUplinkCarrierBand (ulEarfcn) !=
|
||||
LteSpectrumValueHelper::GetUplinkCarrierBand (it.m_ulEarfcn)
|
||||
|| LteSpectrumValueHelper::GetDownlinkCarrierBand (dlEarfcn) !=
|
||||
LteSpectrumValueHelper::GetDownlinkCarrierBand (it.m_dlEarfcn))
|
||||
{
|
||||
NS_FATAL_ERROR ("Band is not wide enough to allocate " << m_numberOfComponentCarriers << " CCs");
|
||||
}
|
||||
|
||||
ConfigToCheck cc;
|
||||
cc.m_dlBandwidth = it.m_dlBandwidth;
|
||||
cc.m_dlEarfcn = dlEarfcn;
|
||||
cc.m_ulBandwidth = it.m_ulBandwidth;
|
||||
cc.m_ulEarfcn = ulEarfcn;
|
||||
|
||||
ccmap.insert (std::pair<uint16_t, ConfigToCheck> (i, cc));
|
||||
|
||||
NS_LOG_INFO ("UL BW: " << it.m_ulBandwidth <<
|
||||
", DL BW: " << it.m_dlBandwidth <<
|
||||
", UL Earfcn: " << ulEarfcn <<
|
||||
", DL Earfcn: " << dlEarfcn);
|
||||
|
||||
// The spacing between the center frequencies of two contiguous CCs should be multiple of 300 kHz.
|
||||
// Round spacing up to 300 kHz.
|
||||
uint32_t frequencyShift = 300 * (1 + (maxBandwidthKhz - 1) / 300);
|
||||
|
||||
// Unit of EARFCN corresponds to 100kHz.
|
||||
uint32_t earfcnShift = frequencyShift / 100;
|
||||
ulEarfcn += earfcnShift;
|
||||
dlEarfcn += earfcnShift;
|
||||
}
|
||||
|
||||
configToCheckContainer.push_back (ccmap);
|
||||
}
|
||||
|
||||
return configToCheckContainer;
|
||||
}
|
||||
|
||||
void
|
||||
CarrierAggregationConfigTestCase::Evaluate (std::string context, Ptr<LteUeRrc> ueRrc, std::list<LteRrcSap::SCellToAddMod> sCellToAddModList)
|
||||
{
|
||||
NS_LOG_INFO ("Secondary carriers configured");
|
||||
|
||||
uint16_t cellId = ueRrc->GetCellId ();
|
||||
NS_LOG_INFO ("cellId " << cellId);
|
||||
NS_LOG_INFO ("m_configToCheckContainer size " << m_configToCheckContainer.size ());
|
||||
|
||||
++m_connectionCounter;
|
||||
|
||||
std::map<uint16_t, ConfigToCheck> configToCheckMap;
|
||||
|
||||
if (cellId == 1)
|
||||
{
|
||||
configToCheckMap = m_configToCheckContainer[cellId-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t n1 = std::max(cellId, m_numberOfComponentCarriers);
|
||||
uint16_t n2 = std::min(cellId, m_numberOfComponentCarriers);
|
||||
configToCheckMap = m_configToCheckContainer[n1-n2];
|
||||
}
|
||||
|
||||
NS_LOG_INFO ("PCarrier - UL BW: " << static_cast<uint16_t> (ueRrc->GetUlBandwidth ()) <<
|
||||
", DL BW: " << static_cast<uint16_t> (ueRrc->GetDlBandwidth ()) <<
|
||||
", UL Earfcn: " << ueRrc->GetUlEarfcn () <<
|
||||
", DL Earfcn: " << ueRrc->GetDlEarfcn ());
|
||||
|
||||
for (auto scell: sCellToAddModList)
|
||||
{
|
||||
NS_LOG_INFO ("SCarrier - UL BW: " << static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth)<<
|
||||
", DL BW: " << static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth) <<
|
||||
", UL Earfcn: " << scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq <<
|
||||
", DL Earfcn: " << scell.cellIdentification.dlCarrierFreq);
|
||||
}
|
||||
|
||||
ConfigToCheck pCConfig = configToCheckMap[0]; // Primary Carrier
|
||||
ConfigToCheck sCConfig; // Secondary Carriers
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (pCConfig.m_dlBandwidth, static_cast<uint16_t> (ueRrc->GetDlBandwidth ()),
|
||||
"Primary Carrier DL bandwidth configuration failed");
|
||||
NS_TEST_ASSERT_MSG_EQ (pCConfig.m_ulBandwidth, static_cast<uint16_t> (ueRrc->GetUlBandwidth ()),
|
||||
"Primary Carrier UL bandwidth configuration failed");
|
||||
NS_TEST_ASSERT_MSG_EQ (pCConfig.m_dlEarfcn, ueRrc->GetDlEarfcn (),
|
||||
"Primary Carrier DL EARFCN configuration failed");
|
||||
NS_TEST_ASSERT_MSG_EQ (pCConfig.m_ulEarfcn, ueRrc->GetUlEarfcn (),
|
||||
"Primary Carrier UL EARFCN configuration failed");
|
||||
|
||||
uint32_t ConfigToCheckMapIndex = 1;
|
||||
|
||||
for (auto scell: sCellToAddModList)
|
||||
{
|
||||
sCConfig = configToCheckMap[ConfigToCheckMapIndex];
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (sCConfig.m_dlBandwidth, static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth),
|
||||
"Secondary Carrier DL bandwidth configuration failed");
|
||||
NS_TEST_ASSERT_MSG_EQ (sCConfig.m_ulBandwidth, static_cast<uint16_t> (scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth),
|
||||
"Secondary Carrier UL bandwidth configuration failed");
|
||||
NS_TEST_ASSERT_MSG_EQ (sCConfig.m_dlEarfcn, scell.cellIdentification.dlCarrierFreq,
|
||||
"Secondary Carrier DL EARFCN configuration failed");
|
||||
NS_TEST_ASSERT_MSG_EQ (sCConfig.m_ulEarfcn, scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq,
|
||||
"Secondary Carrier UL EARFCN configuration failed");
|
||||
ConfigToCheckMapIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CarrierAggregationConfigTestCase::DoRun ()
|
||||
{
|
||||
Config::SetDefault ("ns3::LteHelper::UseCa", BooleanValue (true));
|
||||
Config::SetDefault ("ns3::LteHelper::NumberOfComponentCarriers", UintegerValue (m_numberOfComponentCarriers));
|
||||
Config::SetDefault ("ns3::LteHelper::EnbComponentCarrierManager", StringValue ("ns3::RrComponentCarrierManager"));
|
||||
|
||||
int64_t stream = 1;
|
||||
|
||||
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
|
||||
|
||||
// Create Nodes: eNodeB and UE
|
||||
NodeContainer enbNodes;
|
||||
NodeContainer ueNodes;
|
||||
enbNodes.Create (m_numberOfNodes);
|
||||
ueNodes.Create (m_numberOfNodes);
|
||||
|
||||
uint32_t totalNumberOfNodes = enbNodes.GetN () + ueNodes.GetN ();
|
||||
|
||||
// Install Mobility Model
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
for (uint16_t i = 0; i < totalNumberOfNodes; i++)
|
||||
{
|
||||
positionAlloc->Add (Vector (2 * i, 0, 0));
|
||||
}
|
||||
|
||||
MobilityHelper mobility;
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.SetPositionAllocator (positionAlloc);
|
||||
|
||||
for (uint32_t n = 0; n < m_numberOfNodes; ++n)
|
||||
{
|
||||
mobility.Install (enbNodes.Get (n));
|
||||
mobility.Install (ueNodes.Get (n));
|
||||
}
|
||||
|
||||
ConfigToCheck configuration;
|
||||
NetDeviceContainer enbDevs;
|
||||
NetDeviceContainer ueDevs;
|
||||
|
||||
// Set bandwidth, EARFCN and install nodes (eNB and UE)
|
||||
for (uint32_t i = 0; i < m_configToCheck.size (); ++i)
|
||||
{
|
||||
configuration = m_configToCheck[i];
|
||||
|
||||
lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (configuration.m_dlBandwidth));
|
||||
lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (configuration.m_ulBandwidth));
|
||||
lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (configuration.m_dlEarfcn));
|
||||
lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (configuration.m_ulEarfcn));
|
||||
lteHelper->SetUeDeviceAttribute ("DlEarfcn", UintegerValue (configuration.m_dlEarfcn));
|
||||
enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (i)));
|
||||
lteHelper->AssignStreams (enbDevs, stream);
|
||||
ueDevs.Add (lteHelper->InstallUeDevice (ueNodes.Get (i)));
|
||||
lteHelper->AssignStreams (ueDevs, stream);
|
||||
}
|
||||
|
||||
// Calculate the DlBandwidth, UlBandwidth, DlEarfcn and UlEarfcn to which the values from UE RRC would be compared
|
||||
m_configToCheckContainer = EquallySpacedCcs ();
|
||||
|
||||
// Attach a UE to an eNB
|
||||
for(uint32_t k = 0; k < m_numberOfNodes; ++k)
|
||||
{
|
||||
lteHelper->Attach (ueDevs.Get (k), enbDevs.Get (k));
|
||||
}
|
||||
|
||||
// Activate a data radio bearer
|
||||
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
|
||||
EpsBearer bearer (q);
|
||||
lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
|
||||
|
||||
Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/SCarrierConfigured",
|
||||
MakeCallback (&CarrierAggregationConfigTestCase::Evaluate, this));
|
||||
|
||||
Simulator::Stop (m_simulationDuration);
|
||||
Simulator::Run ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (m_connectionCounter, ueNodes.GetN (), "Not all the UEs were connected");
|
||||
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
|
||||
class CarrierAggregationConfigTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
CarrierAggregationConfigTestSuite ();
|
||||
};
|
||||
|
||||
CarrierAggregationConfigTestSuite::CarrierAggregationConfigTestSuite ()
|
||||
: TestSuite ("lte-carrier-aggregation-configuration", SYSTEM)
|
||||
{
|
||||
std::vector<ConfigToCheck> configToCheck;
|
||||
|
||||
// Test1 with 1 eNB and 1 UE.
|
||||
// We put a configuration different than the default configuration done in LteHelper for the sake of
|
||||
// creating PHY and MAC instances equal to the number of component carriers.
|
||||
|
||||
ConfigToCheck configToCheckTest1;
|
||||
configToCheckTest1.m_dlBandwidth = 50;
|
||||
configToCheckTest1.m_ulBandwidth = 50;
|
||||
configToCheckTest1.m_dlEarfcn = 300;
|
||||
configToCheckTest1.m_ulEarfcn = 300+18000;
|
||||
configToCheck.push_back (configToCheckTest1);
|
||||
uint32_t numberOfNodes = 1;
|
||||
uint16_t numberOfComponentCarriers = 2;
|
||||
Time simulationDuration = Seconds (1);
|
||||
|
||||
AddTestCase (new CarrierAggregationConfigTestCase (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration), TestCase::QUICK);
|
||||
|
||||
// configToCheck.erase(configToCheck.begin(), configToCheck.end());
|
||||
configToCheck.clear ();
|
||||
|
||||
// Test2 with 2 eNBs and 2 UEs.
|
||||
// We decrease the bandwidth so not to exceed maximum band bandwidth of 20 MHz
|
||||
|
||||
configToCheckTest1.m_dlBandwidth = 25;
|
||||
configToCheckTest1.m_ulBandwidth = 25;
|
||||
configToCheckTest1.m_dlEarfcn = 300;
|
||||
configToCheckTest1.m_ulEarfcn = 300+18000;
|
||||
configToCheck.push_back (configToCheckTest1);
|
||||
|
||||
ConfigToCheck configToCheckTest2;
|
||||
configToCheckTest2.m_dlBandwidth = 25;
|
||||
configToCheckTest2.m_ulBandwidth = 25;
|
||||
configToCheckTest2.m_dlEarfcn = 502;
|
||||
configToCheckTest2.m_ulEarfcn = 502+18000;
|
||||
configToCheck.push_back (configToCheckTest2);
|
||||
numberOfNodes = 2;
|
||||
simulationDuration = Seconds (2);
|
||||
|
||||
AddTestCase (new CarrierAggregationConfigTestCase (numberOfNodes, numberOfComponentCarriers, configToCheck, simulationDuration), TestCase::QUICK);
|
||||
}
|
||||
|
||||
static CarrierAggregationConfigTestSuite g_carrierAggregationConfigTestSuite;
|
||||
@@ -191,7 +191,8 @@ def build(bld):
|
||||
'test/lte-simple-spectrum-phy.cc',
|
||||
'test/lte-test-carrier-aggregation.cc',
|
||||
'test/lte-test-aggregation-throughput-scale.cc',
|
||||
'test/lte-test-ipv6-routing.cc'
|
||||
'test/lte-test-ipv6-routing.cc',
|
||||
'test/lte-test-carrier-aggregation-configuration.cc'
|
||||
]
|
||||
|
||||
headers = bld(features='ns3header')
|
||||
|
||||
Reference in New Issue
Block a user