Split UE measurements tests into multiple test suites (still problem with operator redefinition)
This commit is contained in:
379
src/lte/test/lte-test-ue-measurements-handover.cc
Normal file
379
src/lte/test/lte-test-ue-measurements-handover.cc
Normal file
@@ -0,0 +1,379 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Magister Solutions
|
||||
*
|
||||
* 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: Budiarto Herman <budiarto.herman@magister.fi>
|
||||
*/
|
||||
|
||||
#include "lte-test-ue-measurements-handover.h"
|
||||
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/callback.h>
|
||||
#include <ns3/config.h>
|
||||
#include <ns3/boolean.h>
|
||||
|
||||
#include <ns3/lte-helper.h>
|
||||
#include <ns3/epc-helper.h>
|
||||
#include <ns3/internet-stack-helper.h>
|
||||
#include <ns3/point-to-point-helper.h>
|
||||
#include <ns3/ipv4-address-helper.h>
|
||||
#include <ns3/ipv4-static-routing-helper.h>
|
||||
#include <ns3/mobility-helper.h>
|
||||
#include <ns3/node-container.h>
|
||||
#include <ns3/net-device-container.h>
|
||||
#include <ns3/ipv4-interface-container.h>
|
||||
|
||||
#include <ns3/lte-ue-net-device.h>
|
||||
#include <ns3/lte-enb-net-device.h>
|
||||
#include <ns3/lte-enb-rrc.h>
|
||||
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LteUeMeasurementsHandoverTest");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
/*
|
||||
* Overloaded operators, for the convenience of defining test cases, within a
|
||||
* macro guard to avoid defining multiple times.
|
||||
*/
|
||||
|
||||
#ifndef LTE_TEST_UE_MEASUREMENTS_OPERATORS
|
||||
#define LTE_TEST_UE_MEASUREMENTS_OPERATORS
|
||||
|
||||
std::vector<Time>&
|
||||
operator<< (std::vector<Time>& v, const uint64_t& ms)
|
||||
{
|
||||
/*
|
||||
* Prior attempt to use seconds as unit of choice resulted in precision lost.
|
||||
* Therefore milliseconds are used now instead.
|
||||
*/
|
||||
v.push_back (MilliSeconds (ms));
|
||||
return v;
|
||||
}
|
||||
|
||||
std::vector<uint8_t>&
|
||||
operator<< (std::vector<uint8_t>& v, const uint8_t& range)
|
||||
{
|
||||
v.push_back (range);
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif /* LTE_TEST_UE_MEASUREMENTS_OPERATORS */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test Suite
|
||||
*/
|
||||
|
||||
LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite ()
|
||||
: TestSuite ("lte-ue-measurements-handover", SYSTEM)
|
||||
{
|
||||
//LogComponentEnableAll (LOG_PREFIX_ALL);
|
||||
//LogComponentEnable ("LteUeMeasurementsHandoverTest", LOG_INFO);
|
||||
//LogComponentEnable ("LteUeMeasurementsHandoverTest", LOG_DEBUG);
|
||||
//LogComponentEnable ("LteUeMeasurementsHandoverTest", LOG_FUNCTION);
|
||||
//LogComponentEnable ("LteEnbRrc", LOG_FUNCTION);
|
||||
//LogComponentEnable ("LteEnbRrc", LOG_LOGIC);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_INFO);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_WARN);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_LOGIC);
|
||||
|
||||
std::vector<Time> expectedTime;
|
||||
std::vector<uint8_t> expectedRsrp;
|
||||
|
||||
// === Event A1 (serving cell becomes better than threshold) ===
|
||||
|
||||
// With very low threshold
|
||||
LteRrcSap::ReportConfigEutra sourceConfig;
|
||||
sourceConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
|
||||
sourceConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
|
||||
sourceConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
|
||||
sourceConfig.threshold1.range = 0;
|
||||
sourceConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
|
||||
sourceConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS480;
|
||||
LteRrcSap::ReportConfigEutra targetConfig;
|
||||
targetConfig.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
|
||||
targetConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
|
||||
targetConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
|
||||
targetConfig.threshold1.range = 0;
|
||||
targetConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
|
||||
targetConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 680 << 1200 << 1440 << 1680 << 1920;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 55 << 55 << 53 << 53 << 53 << 53;
|
||||
AddTestCase (new LteUeMeasurementsHandoverTestCase ("Handover test case",
|
||||
sourceConfig, targetConfig,
|
||||
expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
} // end of LteUeMeasurementsHandoverTestSuite::LteUeMeasurementsHandoverTestSuite
|
||||
|
||||
|
||||
static LteUeMeasurementsHandoverTestSuite lteUeMeasurementsHandoverTestSuite;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test Case
|
||||
*/
|
||||
|
||||
LteUeMeasurementsHandoverTestCase::LteUeMeasurementsHandoverTestCase (
|
||||
std::string name,
|
||||
LteRrcSap::ReportConfigEutra sourceConfig,
|
||||
LteRrcSap::ReportConfigEutra targetConfig,
|
||||
std::vector<Time> expectedTime,
|
||||
std::vector<uint8_t> expectedRsrp)
|
||||
: TestCase (name),
|
||||
m_sourceConfig (sourceConfig),
|
||||
m_targetConfig (targetConfig),
|
||||
m_expectedTime (expectedTime),
|
||||
m_expectedRsrp (expectedRsrp)
|
||||
{
|
||||
// input sanity check
|
||||
uint16_t size = m_expectedTime.size ();
|
||||
|
||||
if (size != m_expectedRsrp.size ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
|
||||
}
|
||||
|
||||
m_itExpectedTime = m_expectedTime.begin ();
|
||||
m_itExpectedRsrp = m_expectedRsrp.begin ();
|
||||
|
||||
NS_LOG_INFO (this << " name=" << name);
|
||||
}
|
||||
|
||||
|
||||
LteUeMeasurementsHandoverTestCase::~LteUeMeasurementsHandoverTestCase ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsHandoverTestCase::DoRun ()
|
||||
{
|
||||
NS_LOG_INFO (this << " " << GetName ());
|
||||
|
||||
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
|
||||
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
|
||||
lteHelper->SetEpcHelper (epcHelper);
|
||||
lteHelper->SetAttribute ("PathlossModel",
|
||||
StringValue ("ns3::FriisSpectrumPropagationLossModel"));
|
||||
lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
|
||||
|
||||
// Create Nodes: eNodeB and UE
|
||||
NodeContainer enbNodes;
|
||||
NodeContainer ueNodes;
|
||||
enbNodes.Create (2);
|
||||
ueNodes.Create (1);
|
||||
|
||||
/*
|
||||
* The topology is the following:
|
||||
*
|
||||
* eNodeB UE eNodeB
|
||||
* | | |
|
||||
* x ------------------- x ----------------------- x
|
||||
* 400 m 500 m
|
||||
*/
|
||||
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Source eNodeB
|
||||
positionAlloc->Add (Vector (900.0, 0.0, 0.0)); // Target eNodeB
|
||||
positionAlloc->Add (Vector (400.0, 0.0, 0.0)); // UE
|
||||
MobilityHelper mobility;
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.SetPositionAllocator (positionAlloc);
|
||||
mobility.Install (enbNodes);
|
||||
mobility.Install (ueNodes);
|
||||
|
||||
// Create P-GW node
|
||||
Ptr<Node> pgw = epcHelper->GetPgwNode ();
|
||||
|
||||
// Create a single RemoteHost
|
||||
NodeContainer remoteHostContainer;
|
||||
remoteHostContainer.Create (1);
|
||||
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
|
||||
InternetStackHelper internet;
|
||||
internet.Install (remoteHostContainer);
|
||||
|
||||
// Create the Internet
|
||||
PointToPointHelper p2ph;
|
||||
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
|
||||
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
|
||||
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
|
||||
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
|
||||
Ipv4AddressHelper ipv4h;
|
||||
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
|
||||
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
|
||||
|
||||
// Routing of the Internet Host (towards the LTE network)
|
||||
Ipv4StaticRoutingHelper ipv4RoutingHelper;
|
||||
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
|
||||
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
|
||||
|
||||
// Enable layer-3 filtering
|
||||
Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
|
||||
UintegerValue (4));
|
||||
|
||||
// Disable control channel error model
|
||||
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled",
|
||||
BooleanValue (false));
|
||||
|
||||
// Create Devices and install them in the Nodes (eNB and UE)
|
||||
NetDeviceContainer enbDevs;
|
||||
NetDeviceContainer ueDevs;
|
||||
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
|
||||
ueDevs = lteHelper->InstallUeDevice (ueNodes);
|
||||
|
||||
// Setup UE measurement configuration in source eNodeB
|
||||
Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
|
||||
uint8_t measId = enbRrc1->AddUeMeasReportConfig (m_sourceConfig);
|
||||
NS_ASSERT (measId == 1);
|
||||
|
||||
// Setup UE measurement configuration in target eNodeB
|
||||
Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
|
||||
measId = enbRrc2->AddUeMeasReportConfig (m_targetConfig);
|
||||
NS_ASSERT (measId == 1);
|
||||
|
||||
// Install the IP stack on the UEs
|
||||
internet.Install (ueNodes);
|
||||
Ipv4InterfaceContainer ueIpIfaces;
|
||||
ueIpIfaces = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
|
||||
|
||||
// Assign IP address to UEs
|
||||
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
|
||||
{
|
||||
Ptr<Node> ueNode = ueNodes.Get (u);
|
||||
// Set the default gateway for the UE
|
||||
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
|
||||
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
|
||||
}
|
||||
|
||||
// Attach UE to serving eNodeB
|
||||
lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
|
||||
|
||||
// Add X2 interface
|
||||
lteHelper->AddX2Interface (enbNodes);
|
||||
|
||||
// Connect to trace sources in source eNodeB
|
||||
Config::Connect ("/NodeList/1/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
|
||||
MakeCallback (&LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback,
|
||||
this));
|
||||
|
||||
// Connect to trace sources in target eNodeB
|
||||
Config::Connect ("/NodeList/2/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
|
||||
MakeCallback (&LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback,
|
||||
this));
|
||||
|
||||
// Schedule handover
|
||||
lteHelper->HandoverRequest (Seconds (1), ueDevs.Get (0), enbDevs.Get (0),
|
||||
enbDevs.Get (1));
|
||||
|
||||
// Run simulation
|
||||
Simulator::Stop (Seconds (2));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
} // end of void LteUeMeasurementsHandoverTestCase::DoRun ()
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsHandoverTestCase::DoTeardown ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
|
||||
NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
|
||||
"Reporting should have occurred at " << m_itExpectedTime->GetSeconds () << "s");
|
||||
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
|
||||
NS_ASSERT (hasEnded);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback (
|
||||
std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << context);
|
||||
|
||||
// verifying the report completeness
|
||||
LteRrcSap::MeasResults measResults = report.measResults;
|
||||
NS_TEST_ASSERT_MSG_EQ (measResults.measId, 1,
|
||||
"Unexpected measurement identity");
|
||||
double rsrpDbm = EutranMeasurementMapping::RsrpRange2Dbm (measResults.rsrpResult);
|
||||
double rsrqDb = EutranMeasurementMapping::RsrqRange2Db (measResults.rsrqResult);
|
||||
NS_LOG_DEBUG (this << " Serving cellId=" << cellId
|
||||
<< " rsrp=" << (uint16_t) measResults.rsrpResult
|
||||
<< " (" << rsrpDbm << " dBm)"
|
||||
<< " rsrq=" << (uint16_t) measResults.rsrqResult
|
||||
<< " (" << rsrqDb << " dB)");
|
||||
NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, true,
|
||||
"Report does not have neighboring cells information");
|
||||
|
||||
// verifying reported best cells
|
||||
if (measResults.measResultListEutra.size () == 1)
|
||||
{
|
||||
std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
|
||||
NS_ASSERT (it != measResults.measResultListEutra.end ());
|
||||
NS_ASSERT (it->physCellId == 2);
|
||||
NS_TEST_ASSERT_MSG_EQ (it->haveCgiInfo, false,
|
||||
"Report contains cgi-info, which is not supported");
|
||||
NS_TEST_ASSERT_MSG_EQ (it->haveRsrpResult, true,
|
||||
"Report does not contain measured RSRP result");
|
||||
NS_TEST_ASSERT_MSG_EQ (it->haveRsrqResult, true,
|
||||
"Report does not contain measured RSRQ result");
|
||||
rsrpDbm = EutranMeasurementMapping::RsrpRange2Dbm (it->rsrpResult);
|
||||
rsrqDb = EutranMeasurementMapping::RsrqRange2Db (it->rsrqResult);
|
||||
NS_LOG_DEBUG (this << " Neighbour cellId=" << it->physCellId
|
||||
<< " rsrp=" << (uint16_t) it->rsrpResult
|
||||
<< " (" << rsrpDbm << " dBm)"
|
||||
<< " rsrq=" << (uint16_t) it->rsrqResult
|
||||
<< " (" << rsrqDb << " dB)");
|
||||
}
|
||||
|
||||
// verifying the report timing
|
||||
bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
|
||||
NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
|
||||
"Reporting should not have occurred at "
|
||||
<< Simulator::Now ().GetSeconds () << "s");
|
||||
if (!hasEnded)
|
||||
{
|
||||
// comparison with milliseconds to avoid floating-point comparison
|
||||
uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
|
||||
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
|
||||
NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
|
||||
"Reporting should not have occurred at this time");
|
||||
m_itExpectedTime++;
|
||||
|
||||
// verifying the report RSRP content
|
||||
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
|
||||
NS_ASSERT (!hasEnded);
|
||||
uint16_t observedRsrp = measResults.rsrpResult;
|
||||
uint16_t referenceRsrp = *m_itExpectedRsrp;
|
||||
NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
|
||||
"The RSRP observed differs with the reference RSRP");
|
||||
m_itExpectedRsrp++;
|
||||
}
|
||||
|
||||
} // end of void LteUeMeasurementsHandoverTestCase::RecvMeasurementReportCallback
|
||||
|
||||
|
||||
} // end of namespace ns3
|
||||
130
src/lte/test/lte-test-ue-measurements-handover.h
Normal file
130
src/lte/test/lte-test-ue-measurements-handover.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Magister Solutions
|
||||
*
|
||||
* 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: Budiarto Herman <budiarto.herman@magister.fi>
|
||||
*/
|
||||
|
||||
#ifndef LTE_TEST_UE_MEASUREMENTS_HANDOVER_H
|
||||
#define LTE_TEST_UE_MEASUREMENTS_HANDOVER_H
|
||||
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/lte-rrc-sap.h>
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Time;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test suite for generating calls to UE measurements test case
|
||||
* ns3::LteUeMeasurementsHandoverTestCase.
|
||||
*/
|
||||
class LteUeMeasurementsHandoverTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsHandoverTestSuite ();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in
|
||||
* a handover configuration.
|
||||
*
|
||||
* The simulation will run for 2 seconds, while the handover command will be
|
||||
* issued at second +1s.
|
||||
*/
|
||||
class LteUeMeasurementsHandoverTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsHandoverTestCase (std::string name,
|
||||
LteRrcSap::ReportConfigEutra sourceConfig,
|
||||
LteRrcSap::ReportConfigEutra targetConfig,
|
||||
std::vector<Time> expectedTime,
|
||||
std::vector<uint8_t> expectedRsrp);
|
||||
|
||||
virtual ~LteUeMeasurementsHandoverTestCase ();
|
||||
|
||||
/**
|
||||
* \brief Triggers when either one of the eNodeBs receives measurement report
|
||||
* from UE, then perform verification on it.
|
||||
*
|
||||
* The trigger is set up beforehand by connecting to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*
|
||||
* Verification consists of checking whether the report carries the right
|
||||
* value of RSRP or not, and whether it occurs at the expected time or not.
|
||||
*/
|
||||
void RecvMeasurementReportCallback (std::string context, uint64_t imsi,
|
||||
uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Setup the simulation with the intended UE measurement reporting
|
||||
* configuration, run it, and connect the
|
||||
* `RecvMeasurementReportCallback` function to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*/
|
||||
virtual void DoRun ();
|
||||
|
||||
/**
|
||||
* \brief Runs at the end of the simulation, verifying that all expected
|
||||
* measurement reports have been examined.
|
||||
*/
|
||||
virtual void DoTeardown ();
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration for the source eNodeB.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_sourceConfig;
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration for the target eNodeB.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_targetConfig;
|
||||
|
||||
/**
|
||||
* \brief The list of expected time when measurement reports are received by
|
||||
* eNodeB.
|
||||
*/
|
||||
std::vector<Time> m_expectedTime;
|
||||
|
||||
/**
|
||||
* \brief The list of expected values of RSRP (in 3GPP range unit) from the
|
||||
* measurement reports received.
|
||||
*/
|
||||
std::vector<uint8_t> m_expectedRsrp;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedTime` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<Time>::iterator m_itExpectedTime;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedRsrp` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<uint8_t>::iterator m_itExpectedRsrp;
|
||||
|
||||
}; // end of class LteUeMeasurementsHandoverTestCase
|
||||
|
||||
|
||||
} // end of namespace ns3
|
||||
|
||||
#endif /* LTE_TEST_UE_MEASUREMENTS_HANDOVER_H */
|
||||
520
src/lte/test/lte-test-ue-measurements-piecewise-1.cc
Normal file
520
src/lte/test/lte-test-ue-measurements-piecewise-1.cc
Normal file
@@ -0,0 +1,520 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Magister Solutions
|
||||
*
|
||||
* 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: Budiarto Herman <budiarto.herman@magister.fi>
|
||||
*/
|
||||
|
||||
#include "lte-test-ue-measurements-piecewise-1.h"
|
||||
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/callback.h>
|
||||
#include <ns3/config.h>
|
||||
#include <ns3/boolean.h>
|
||||
#include <ns3/enum.h>
|
||||
|
||||
#include <ns3/lte-helper.h>
|
||||
#include <ns3/internet-stack-helper.h>
|
||||
#include <ns3/point-to-point-helper.h>
|
||||
#include <ns3/ipv4-address-helper.h>
|
||||
#include <ns3/ipv4-static-routing-helper.h>
|
||||
#include <ns3/mobility-helper.h>
|
||||
#include <ns3/node-container.h>
|
||||
#include <ns3/net-device-container.h>
|
||||
#include <ns3/ipv4-interface-container.h>
|
||||
|
||||
#include <ns3/lte-ue-net-device.h>
|
||||
#include <ns3/lte-enb-net-device.h>
|
||||
#include <ns3/lte-enb-rrc.h>
|
||||
#include <ns3/ff-mac-scheduler.h>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LteUeMeasurementsPiecewiseTest1");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
/*
|
||||
* Overloaded operators, for the convenience of defining test cases, within a
|
||||
* macro guard to avoid defining multiple times.
|
||||
*/
|
||||
|
||||
#ifndef LTE_TEST_UE_MEASUREMENTS_OPERATORS
|
||||
#define LTE_TEST_UE_MEASUREMENTS_OPERATORS
|
||||
|
||||
std::vector<Time>&
|
||||
operator<< (std::vector<Time>& v, const uint64_t& ms)
|
||||
{
|
||||
/*
|
||||
* Prior attempt to use seconds as unit of choice resulted in precision lost.
|
||||
* Therefore milliseconds are used now instead.
|
||||
*/
|
||||
v.push_back (MilliSeconds (ms));
|
||||
return v;
|
||||
}
|
||||
|
||||
std::vector<uint8_t>&
|
||||
operator<< (std::vector<uint8_t>& v, const uint8_t& range)
|
||||
{
|
||||
v.push_back (range);
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif /* LTE_TEST_UE_MEASUREMENTS_OPERATORS */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test Suite
|
||||
*/
|
||||
|
||||
LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1 ()
|
||||
: TestSuite ("lte-ue-measurements-piecewise-1", SYSTEM)
|
||||
{
|
||||
//LogComponentEnableAll (LOG_PREFIX_ALL);
|
||||
//LogComponentEnable ("LteUeMeasurementsPiecewiseTest1", LOG_INFO);
|
||||
//LogComponentEnable ("LteUeMeasurementsPiecewiseTest1", LOG_DEBUG);
|
||||
//LogComponentEnable ("LteUeMeasurementsPiecewiseTest1", LOG_FUNCTION);
|
||||
//LogComponentEnable ("LteEnbRrc", LOG_FUNCTION);
|
||||
//LogComponentEnable ("LteEnbRrc", LOG_LOGIC);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_INFO);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_WARN);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_LOGIC);
|
||||
|
||||
std::vector<Time> expectedTime;
|
||||
std::vector<uint8_t> expectedRsrp;
|
||||
|
||||
// === Event A1 (serving cell becomes better than threshold) ===
|
||||
|
||||
// With very low threshold
|
||||
LteRrcSap::ReportConfigEutra config;
|
||||
config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
|
||||
config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
|
||||
config.threshold1.range = 0;
|
||||
config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
|
||||
config.reportInterval = LteRrcSap::ReportConfigEutra::MS120;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280
|
||||
<< 1400 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57
|
||||
<< 51 << 51 << 47 << 47 << 51 << 57 << 57;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with very low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal threshold
|
||||
config.threshold1.range = 54;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 320 << 440 << 560 << 680 << 1000 << 1120 << 1240 << 1360 << 2000
|
||||
<< 2120;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 67 << 67 << 57 << 57 << 66 << 66 << 66 << 57 << 57 << 57
|
||||
<< 57;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With very high threshold
|
||||
config.threshold1.range = 97;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A1 with very high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A2 (serving cell becomes worse than threshold) ===
|
||||
|
||||
// With very low threshold
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
|
||||
config.threshold1.range = 0;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with very low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal threshold
|
||||
config.threshold1.range = 54;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 800 << 920 << 1400 << 1520 << 1640 << 1760 << 1880;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 47 << 47 << 51 << 51 << 47 << 47 << 51;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With very high threshold
|
||||
config.threshold1.range = 97;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 320 << 440 << 560 << 680 << 800 << 920 << 1040 << 1160 << 1280
|
||||
<< 1400 << 1520 << 1640 << 1760 << 1880 << 2000 << 2120;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 67 << 67 << 57 << 57 << 66 << 47 << 47 << 66 << 66 << 57
|
||||
<< 51 << 51 << 47 << 47 << 51 << 57 << 57;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A2 with very high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A3 (neighbour becomes offset better than PCell) ===
|
||||
|
||||
// With positive offset
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
|
||||
config.threshold1.range = 0;
|
||||
config.a3Offset = 7;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A3 with positive offset",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With zero offset
|
||||
config.a3Offset = 0;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A3 with zero offset",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With negative offset
|
||||
config.a3Offset = -7;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A3 with negative offset",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A4 (neighbour becomes better than threshold) ===
|
||||
|
||||
// With very low threshold
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
|
||||
config.threshold1.range = 0;
|
||||
config.a3Offset = 0;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A4 with very low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal threshold
|
||||
config.threshold1.range = 54;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A4 with normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With very high threshold
|
||||
config.threshold1.range = 97;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A4 with very high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) ===
|
||||
|
||||
// With low-low threshold
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
|
||||
config.threshold1.range = 0;
|
||||
config.threshold2.range = 0;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with low-low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With low-normal threshold
|
||||
config.threshold2.range = 58;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with low-normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With low-high threshold
|
||||
config.threshold2.range = 97;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with low-high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal-low threshold
|
||||
config.threshold1.range = 58;
|
||||
config.threshold2.range = 0;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with normal-low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal-normal threshold
|
||||
config.threshold2.range = 58;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with normal-normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal-high threshold
|
||||
config.threshold2.range = 97;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with normal-high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With high-low threshold
|
||||
config.threshold1.range = 97;
|
||||
config.threshold2.range = 0;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with high-low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With high-normal threshold
|
||||
config.threshold2.range = 58;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with high-normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With high-high threshold
|
||||
config.threshold2.range = 97;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase1 ("Piecewise test case 1 - Event A5 with high-high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
} // end of LteUeMeasurementsPiecewiseTestSuite1::LteUeMeasurementsPiecewiseTestSuite1
|
||||
|
||||
|
||||
static LteUeMeasurementsPiecewiseTestSuite1 lteUeMeasurementsPiecewiseTestSuite1;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test Case
|
||||
*/
|
||||
|
||||
LteUeMeasurementsPiecewiseTestCase1::LteUeMeasurementsPiecewiseTestCase1 (
|
||||
std::string name, LteRrcSap::ReportConfigEutra config,
|
||||
std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp)
|
||||
: TestCase (name),
|
||||
m_config (config),
|
||||
m_expectedTime (expectedTime),
|
||||
m_expectedRsrp (expectedRsrp)
|
||||
{
|
||||
// input sanity check
|
||||
uint16_t size = m_expectedTime.size ();
|
||||
|
||||
if (size != m_expectedRsrp.size ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
|
||||
}
|
||||
|
||||
m_itExpectedTime = m_expectedTime.begin ();
|
||||
m_itExpectedRsrp = m_expectedRsrp.begin ();
|
||||
|
||||
NS_LOG_INFO (this << " name=" << name);
|
||||
}
|
||||
|
||||
|
||||
LteUeMeasurementsPiecewiseTestCase1::~LteUeMeasurementsPiecewiseTestCase1 ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase1::DoRun ()
|
||||
{
|
||||
NS_LOG_INFO (this << " " << GetName ());
|
||||
|
||||
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
|
||||
lteHelper->SetAttribute ("PathlossModel",
|
||||
StringValue ("ns3::FriisSpectrumPropagationLossModel"));
|
||||
lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
|
||||
|
||||
// Create Nodes: eNodeB and UE
|
||||
NodeContainer enbNodes;
|
||||
NodeContainer ueNodes;
|
||||
enbNodes.Create (1);
|
||||
ueNodes.Create (1);
|
||||
|
||||
/*
|
||||
* The topology is the following:
|
||||
*
|
||||
* eNodeB UE
|
||||
* | |
|
||||
* x ----- x --------- x --------------- x ------------------- x
|
||||
* 100 m | 200 m | 300 m | 400 m |
|
||||
* | | | |
|
||||
* VeryNear Near Far VeryFar
|
||||
*/
|
||||
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // eNodeB
|
||||
positionAlloc->Add (Vector (100.0, 0.0, 0.0)); // UE
|
||||
MobilityHelper mobility;
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.SetPositionAllocator (positionAlloc);
|
||||
mobility.Install (enbNodes);
|
||||
mobility.Install (ueNodes);
|
||||
m_ueMobility = ueNodes.Get (0)->GetObject<MobilityModel> ();
|
||||
|
||||
// Disable layer-3 filtering
|
||||
Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
|
||||
UintegerValue (0));
|
||||
|
||||
// Create Devices and install them in the Nodes (eNB and UE)
|
||||
NetDeviceContainer enbDevs;
|
||||
NetDeviceContainer ueDevs;
|
||||
lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
|
||||
lteHelper->SetSchedulerAttribute ("UlCqiFilter",
|
||||
EnumValue (FfMacScheduler::PUSCH_UL_CQI));
|
||||
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
|
||||
ueDevs = lteHelper->InstallUeDevice (ueNodes);
|
||||
|
||||
// Setup UE measurement configuration
|
||||
Ptr<LteEnbRrc> enbRrc = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
|
||||
uint8_t measId = enbRrc->AddUeMeasReportConfig (m_config);
|
||||
NS_ASSERT (measId == 1);
|
||||
|
||||
// Attach UE to eNodeB
|
||||
lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
|
||||
|
||||
// Activate an EPS bearer
|
||||
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
|
||||
EpsBearer bearer (q);
|
||||
lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
|
||||
|
||||
// Connect to trace sources
|
||||
Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
|
||||
MakeCallback (&LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback,
|
||||
this));
|
||||
|
||||
/*
|
||||
* Schedule "teleports"
|
||||
* 0 1 2
|
||||
* +-------------------+-------------------+---------> time
|
||||
* VeryNear |------ ---- ---- --------
|
||||
* Near | ---- ----
|
||||
* Far | ---- ----
|
||||
* VeryFar | -- ---- ----
|
||||
*/
|
||||
Simulator::Schedule (MilliSeconds (301),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar, this);
|
||||
Simulator::Schedule (MilliSeconds (401),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear, this);
|
||||
Simulator::Schedule (MilliSeconds (601),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar, this);
|
||||
Simulator::Schedule (MilliSeconds (801),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear, this);
|
||||
Simulator::Schedule (MilliSeconds (1001),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportNear, this);
|
||||
Simulator::Schedule (MilliSeconds (1201),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportFar, this);
|
||||
Simulator::Schedule (MilliSeconds (1401),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar, this);
|
||||
Simulator::Schedule (MilliSeconds (1601),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportFar, this);
|
||||
Simulator::Schedule (MilliSeconds (1801),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportNear, this);
|
||||
Simulator::Schedule (MilliSeconds (2001),
|
||||
&LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear, this);
|
||||
|
||||
// Run simulation
|
||||
Simulator::Stop (Seconds (2.201));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
} // end of void LteUeMeasurementsPiecewiseTestCase1::DoRun ()
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase1::DoTeardown ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
|
||||
NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
|
||||
"Reporting should have occurred at " << m_itExpectedTime->GetSeconds () << "s");
|
||||
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
|
||||
NS_ASSERT (hasEnded);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback (
|
||||
std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << context);
|
||||
NS_ASSERT (rnti == 1);
|
||||
NS_ASSERT (cellId == 1);
|
||||
|
||||
// verifying the report completeness
|
||||
LteRrcSap::MeasResults measResults = report.measResults;
|
||||
NS_TEST_ASSERT_MSG_EQ (measResults.measId, 1,
|
||||
"Unexpected measurement identity");
|
||||
double rsrpDbm = EutranMeasurementMapping::RsrpRange2Dbm (measResults.rsrpResult);
|
||||
double rsrqDb = EutranMeasurementMapping::RsrqRange2Db (measResults.rsrqResult);
|
||||
NS_LOG_DEBUG (this << " rsrp=" << (uint16_t) measResults.rsrpResult
|
||||
<< " (" << rsrpDbm << " dBm)"
|
||||
<< " rsrq=" << (uint16_t) measResults.rsrqResult
|
||||
<< " (" << rsrqDb << " dB)");
|
||||
NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, true,
|
||||
"Report does not have neighboring cells information");
|
||||
NS_TEST_ASSERT_MSG_EQ (measResults.measResultListEutra.size (), 0,
|
||||
"Unexpected report size");
|
||||
|
||||
// verifying the report timing
|
||||
bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
|
||||
NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
|
||||
"Reporting should not have occurred at "
|
||||
<< Simulator::Now ().GetSeconds () << "s");
|
||||
if (!hasEnded)
|
||||
{
|
||||
// comparison with milliseconds to avoid floating-point comparison
|
||||
uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
|
||||
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
|
||||
NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
|
||||
"Reporting should not have occurred at this time");
|
||||
m_itExpectedTime++;
|
||||
|
||||
// verifying the report RSRP content
|
||||
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
|
||||
NS_ASSERT (!hasEnded);
|
||||
uint16_t observedRsrp = measResults.rsrpResult;
|
||||
uint16_t referenceRsrp = *m_itExpectedRsrp;
|
||||
NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
|
||||
"The RSRP observed differs with the reference RSRP");
|
||||
m_itExpectedRsrp++;
|
||||
}
|
||||
|
||||
} // end of LteUeMeasurementsPiecewiseTestCase1::RecvMeasurementReportCallback
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase1::TeleportVeryNear ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (100.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase1::TeleportNear ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (300.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase1::TeleportFar ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (600.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase1::TeleportVeryFar ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (1000.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace ns3
|
||||
130
src/lte/test/lte-test-ue-measurements-piecewise-1.h
Normal file
130
src/lte/test/lte-test-ue-measurements-piecewise-1.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Magister Solutions
|
||||
*
|
||||
* 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: Budiarto Herman <budiarto.herman@magister.fi>
|
||||
*/
|
||||
|
||||
#ifndef LTE_TEST_UE_MEASUREMENTS_PIECEWISE_1_H
|
||||
#define LTE_TEST_UE_MEASUREMENTS_PIECEWISE_1_H
|
||||
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/ptr.h>
|
||||
#include <ns3/lte-rrc-sap.h>
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class MobilityModel;
|
||||
class Time;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test suite for generating calls to UE measurements test case
|
||||
* ns3::LteUeMeasurementsPiecewiseTestCase1.
|
||||
*/
|
||||
class LteUeMeasurementsPiecewiseTestSuite1 : public TestSuite
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsPiecewiseTestSuite1 ();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Testing UE measurements in LTE with simulation of 1 eNodeB and 1 UE in
|
||||
* piecewise configuration and 120 ms report interval.
|
||||
*/
|
||||
class LteUeMeasurementsPiecewiseTestCase1 : public TestCase
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsPiecewiseTestCase1 (std::string name,
|
||||
LteRrcSap::ReportConfigEutra config,
|
||||
std::vector<Time> expectedTime,
|
||||
std::vector<uint8_t> expectedRsrp);
|
||||
|
||||
virtual ~LteUeMeasurementsPiecewiseTestCase1 ();
|
||||
|
||||
/**
|
||||
* \brief Triggers when eNodeB receives measurement report from UE, then
|
||||
* perform verification on it.
|
||||
*
|
||||
* The trigger is set up beforehand by connecting to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*
|
||||
* Verification consists of checking whether the report carries the right
|
||||
* value of RSRP or not, and whether it occurs at the expected time or not.
|
||||
*/
|
||||
void RecvMeasurementReportCallback (std::string context, uint64_t imsi,
|
||||
uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Setup the simulation with the intended UE measurement reporting
|
||||
* configuration, run it, and connect the
|
||||
* `RecvMeasurementReportCallback` function to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*/
|
||||
virtual void DoRun ();
|
||||
|
||||
/**
|
||||
* \brief Runs at the end of the simulation, verifying that all expected
|
||||
* measurement reports have been examined.
|
||||
*/
|
||||
virtual void DoTeardown ();
|
||||
|
||||
void TeleportVeryNear ();
|
||||
void TeleportNear ();
|
||||
void TeleportFar ();
|
||||
void TeleportVeryFar ();
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_config;
|
||||
|
||||
/**
|
||||
* \brief The list of expected time when measurement reports are received by
|
||||
* eNodeB.
|
||||
*/
|
||||
std::vector<Time> m_expectedTime;
|
||||
|
||||
/**
|
||||
* \brief The list of expected values of RSRP (in 3GPP range unit) from the
|
||||
* measurement reports received.
|
||||
*/
|
||||
std::vector<uint8_t> m_expectedRsrp;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedTime` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<Time>::iterator m_itExpectedTime;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedRsrp` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<uint8_t>::iterator m_itExpectedRsrp;
|
||||
|
||||
Ptr<MobilityModel> m_ueMobility;
|
||||
|
||||
}; // end of class LteUeMeasurementsPiecewiseTestCase1
|
||||
|
||||
|
||||
} // end of namespace ns3
|
||||
|
||||
#endif /* LTE_TEST_UE_MEASUREMENTS_PIECEWISE_1_H */
|
||||
581
src/lte/test/lte-test-ue-measurements-piecewise-2.cc
Normal file
581
src/lte/test/lte-test-ue-measurements-piecewise-2.cc
Normal file
@@ -0,0 +1,581 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Magister Solutions
|
||||
*
|
||||
* 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: Budiarto Herman <budiarto.herman@magister.fi>
|
||||
*/
|
||||
|
||||
#include "lte-test-ue-measurements-piecewise-2.h"
|
||||
|
||||
#include <ns3/simulator.h>
|
||||
#include <ns3/log.h>
|
||||
#include <ns3/callback.h>
|
||||
#include <ns3/config.h>
|
||||
#include <ns3/boolean.h>
|
||||
#include <ns3/enum.h>
|
||||
|
||||
#include <ns3/lte-helper.h>
|
||||
#include <ns3/internet-stack-helper.h>
|
||||
#include <ns3/point-to-point-helper.h>
|
||||
#include <ns3/ipv4-address-helper.h>
|
||||
#include <ns3/ipv4-static-routing-helper.h>
|
||||
#include <ns3/mobility-helper.h>
|
||||
#include <ns3/node-container.h>
|
||||
#include <ns3/net-device-container.h>
|
||||
#include <ns3/ipv4-interface-container.h>
|
||||
|
||||
#include <ns3/lte-ue-net-device.h>
|
||||
#include <ns3/lte-enb-net-device.h>
|
||||
#include <ns3/lte-enb-rrc.h>
|
||||
#include <ns3/ff-mac-scheduler.h>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("LteUeMeasurementsPiecewiseTest2");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
/*
|
||||
* Overloaded operators, for the convenience of defining test cases, within a
|
||||
* macro guard to avoid defining multiple times.
|
||||
*/
|
||||
|
||||
#ifndef LTE_TEST_UE_MEASUREMENTS_OPERATORS
|
||||
#define LTE_TEST_UE_MEASUREMENTS_OPERATORS
|
||||
|
||||
std::vector<Time>&
|
||||
operator<< (std::vector<Time>& v, const uint64_t& ms)
|
||||
{
|
||||
/*
|
||||
* Prior attempt to use seconds as unit of choice resulted in precision lost.
|
||||
* Therefore milliseconds are used now instead.
|
||||
*/
|
||||
v.push_back (MilliSeconds (ms));
|
||||
return v;
|
||||
}
|
||||
|
||||
std::vector<uint8_t>&
|
||||
operator<< (std::vector<uint8_t>& v, const uint8_t& range)
|
||||
{
|
||||
v.push_back (range);
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif /* LTE_TEST_UE_MEASUREMENTS_OPERATORS */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test Suite
|
||||
*/
|
||||
|
||||
LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2 ()
|
||||
: TestSuite ("lte-ue-measurements-piecewise-2", SYSTEM)
|
||||
{
|
||||
//LogComponentEnableAll (LOG_PREFIX_ALL);
|
||||
//LogComponentEnable ("LteUeMeasurementsPiecewiseTest2", LOG_INFO);
|
||||
//LogComponentEnable ("LteUeMeasurementsPiecewiseTest2", LOG_DEBUG);
|
||||
//LogComponentEnable ("LteUeMeasurementsPiecewiseTest2", LOG_FUNCTION);
|
||||
//LogComponentEnable ("LteEnbRrc", LOG_FUNCTION);
|
||||
//LogComponentEnable ("LteEnbRrc", LOG_LOGIC);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_INFO);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_WARN);
|
||||
//LogComponentEnable ("LteUeRrc", LOG_LOGIC);
|
||||
|
||||
std::vector<Time> expectedTime;
|
||||
std::vector<uint8_t> expectedRsrp;
|
||||
|
||||
// === Event A1 (serving cell becomes better than threshold) ===
|
||||
|
||||
// With very low threshold
|
||||
LteRrcSap::ReportConfigEutra config;
|
||||
config.triggerType = LteRrcSap::ReportConfigEutra::EVENT;
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A1;
|
||||
config.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRP;
|
||||
config.threshold1.range = 0;
|
||||
config.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRP;
|
||||
config.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 73 << 63 << 72 << 52 << 72 << 59 << 52 << 56 << 59;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with very low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal threshold
|
||||
config.threshold1.range = 58;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 440 << 680 << 1000 << 1240 << 2000;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 73 << 63 << 72 << 72 << 59 << 59;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With very high threshold
|
||||
config.threshold1.range = 97;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A1 with very high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A2 (serving cell becomes worse than threshold) ===
|
||||
|
||||
// With very low threshold
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A2;
|
||||
config.threshold1.range = 0;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with very low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal threshold
|
||||
config.threshold1.range = 58;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 800 << 1400 << 1640 << 1880;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 52 << 56 << 52 << 56;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With very high threshold
|
||||
config.threshold1.range = 97;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 73 << 63 << 72 << 52 << 72 << 59 << 52 << 56 << 59;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A2 with very high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A3 (neighbour becomes offset better than PCell) ===
|
||||
|
||||
// With positive offset
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A3;
|
||||
config.threshold1.range = 0;
|
||||
config.a3Offset = 7;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 800 << 1600;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 52 << 52;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with positive offset",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With zero offset
|
||||
config.a3Offset = 0;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 800 << 1400 << 1640 << 1880;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 52 << 56 << 52 << 56;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with zero offset",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With negative offset
|
||||
config.a3Offset = -7;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 400 << 800 << 1200 << 1440 << 1680 << 1920 << 2160;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 63 << 52 << 59 << 56 << 52 << 56 << 59;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A3 with negative offset",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A4 (neighbour becomes better than threshold) ===
|
||||
|
||||
// With very low threshold
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
|
||||
config.threshold1.range = 0;
|
||||
config.a3Offset = 0;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 73 << 63 << 72 << 52 << 72 << 59 << 52 << 56 << 59;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with very low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal threshold
|
||||
config.threshold1.range = 58;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 400 << 800 << 1400 << 1640 << 1880;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 63 << 52 << 56 << 52 << 56;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With very high threshold
|
||||
config.threshold1.range = 97;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A4 with very high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// === Event A5 (PCell becomes worse than absolute threshold1 AND neighbour becomes better than another absolute threshold2) ===
|
||||
|
||||
// With low-low threshold
|
||||
config.eventId = LteRrcSap::ReportConfigEutra::EVENT_A5;
|
||||
config.threshold1.range = 0;
|
||||
config.threshold2.range = 0;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With low-normal threshold
|
||||
config.threshold2.range = 58;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With low-high threshold
|
||||
config.threshold2.range = 97;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with low-high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal-low threshold
|
||||
config.threshold1.range = 58;
|
||||
config.threshold2.range = 0;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 800 << 1400 << 1640 << 1880;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 52 << 56 << 52 << 56;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal-normal threshold
|
||||
config.threshold2.range = 58;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 800 << 1400 << 1640 << 1880;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 52 << 56 << 52 << 56;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With normal-high threshold
|
||||
config.threshold2.range = 97;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with normal-high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With high-low threshold
|
||||
config.threshold1.range = 97;
|
||||
config.threshold2.range = 0;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 200 << 440 << 680 << 920 << 1160 << 1400 << 1640 << 1880 << 2120;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 73 << 63 << 72 << 52 << 72 << 59 << 52 << 56 << 59;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-low threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With high-normal threshold
|
||||
config.threshold2.range = 58;
|
||||
expectedTime.clear ();
|
||||
expectedTime << 400 << 800 << 1400 << 1640 << 1880;
|
||||
expectedRsrp.clear ();
|
||||
expectedRsrp << 63 << 52 << 56 << 52 << 56;
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-normal threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
// With high-high threshold
|
||||
config.threshold2.range = 97;
|
||||
expectedTime.clear ();
|
||||
expectedRsrp.clear ();
|
||||
AddTestCase (new LteUeMeasurementsPiecewiseTestCase2 ("Piecewise test case 2 - Event A5 with high-high threshold",
|
||||
config, expectedTime, expectedRsrp),
|
||||
TestCase::EXTENSIVE);
|
||||
|
||||
} // end of LteUeMeasurementsPiecewiseTestSuite2::LteUeMeasurementsPiecewiseTestSuite2
|
||||
|
||||
|
||||
static LteUeMeasurementsPiecewiseTestSuite2 lteUeMeasurementsPiecewiseTestSuite2;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test Case
|
||||
*/
|
||||
|
||||
LteUeMeasurementsPiecewiseTestCase2::LteUeMeasurementsPiecewiseTestCase2 (
|
||||
std::string name, LteRrcSap::ReportConfigEutra config,
|
||||
std::vector<Time> expectedTime, std::vector<uint8_t> expectedRsrp)
|
||||
: TestCase (name),
|
||||
m_config (config),
|
||||
m_expectedTime (expectedTime),
|
||||
m_expectedRsrp (expectedRsrp)
|
||||
{
|
||||
// input sanity check
|
||||
uint16_t size = m_expectedTime.size ();
|
||||
|
||||
if (size != m_expectedRsrp.size ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Vectors of expected results are not of the same size");
|
||||
}
|
||||
|
||||
m_itExpectedTime = m_expectedTime.begin ();
|
||||
m_itExpectedRsrp = m_expectedRsrp.begin ();
|
||||
|
||||
NS_LOG_INFO (this << " name=" << name);
|
||||
}
|
||||
|
||||
|
||||
LteUeMeasurementsPiecewiseTestCase2::~LteUeMeasurementsPiecewiseTestCase2 ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase2::DoRun ()
|
||||
{
|
||||
NS_LOG_INFO (this << " " << GetName ());
|
||||
|
||||
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
|
||||
lteHelper->SetAttribute ("PathlossModel",
|
||||
StringValue ("ns3::FriisSpectrumPropagationLossModel"));
|
||||
lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
|
||||
|
||||
// Create Nodes: eNodeB and UE
|
||||
NodeContainer enbNodes;
|
||||
NodeContainer ueNodes;
|
||||
enbNodes.Create (2);
|
||||
ueNodes.Create (1);
|
||||
|
||||
/*
|
||||
* The topology is the following:
|
||||
*
|
||||
* eNodeB UE eNodeB
|
||||
* | | |
|
||||
* x ---- x --------------- x ------- x --------------- x ---- x
|
||||
* 50 m | 200 m | 100 m | 200 m | 50 m
|
||||
* | | | |
|
||||
* VeryNear Near Far VeryFar
|
||||
*/
|
||||
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // Serving eNodeB
|
||||
positionAlloc->Add (Vector (600.0, 0.0, 0.0)); // Neighbour eNodeB
|
||||
positionAlloc->Add (Vector (50.0, 0.0, 0.0)); // UE
|
||||
MobilityHelper mobility;
|
||||
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
|
||||
mobility.SetPositionAllocator (positionAlloc);
|
||||
mobility.Install (enbNodes);
|
||||
mobility.Install (ueNodes);
|
||||
m_ueMobility = ueNodes.Get (0)->GetObject<MobilityModel> ();
|
||||
|
||||
// Disable layer-3 filtering
|
||||
Config::SetDefault ("ns3::LteEnbRrc::RsrpFilterCoefficient",
|
||||
UintegerValue (0));
|
||||
|
||||
// Create Devices and install them in the Nodes (eNB and UE)
|
||||
NetDeviceContainer enbDevs;
|
||||
NetDeviceContainer ueDevs;
|
||||
lteHelper->SetSchedulerType ("ns3::RrFfMacScheduler");
|
||||
lteHelper->SetSchedulerAttribute ("UlCqiFilter",
|
||||
EnumValue (FfMacScheduler::PUSCH_UL_CQI));
|
||||
enbDevs = lteHelper->InstallEnbDevice (enbNodes);
|
||||
ueDevs = lteHelper->InstallUeDevice (ueNodes);
|
||||
|
||||
// Setup UE measurement configuration in serving cell
|
||||
Ptr<LteEnbRrc> enbRrc1 = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
|
||||
uint8_t measId = enbRrc1->AddUeMeasReportConfig (m_config);
|
||||
NS_ASSERT (measId == 1);
|
||||
|
||||
// Disable handover in neighbour cell
|
||||
Ptr<LteEnbRrc> enbRrc2 = enbDevs.Get (1)->GetObject<LteEnbNetDevice> ()->GetRrc ();
|
||||
enbRrc2->SetAttribute ("AdmitHandoverRequest", BooleanValue (false));
|
||||
|
||||
// Attach UE to serving eNodeB
|
||||
lteHelper->Attach (ueDevs.Get (0), enbDevs.Get (0));
|
||||
|
||||
// Activate an EPS bearer
|
||||
enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
|
||||
EpsBearer bearer (q);
|
||||
lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
|
||||
|
||||
// Connect to trace sources in serving eNodeB
|
||||
Config::Connect ("/NodeList/0/DeviceList/0/LteEnbRrc/RecvMeasurementReport",
|
||||
MakeCallback (&LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback,
|
||||
this));
|
||||
|
||||
/*
|
||||
* Schedule "teleports"
|
||||
* 0 1 2
|
||||
* +-------------------+-------------------+---------> time
|
||||
* VeryNear |------ ---- ---- --------
|
||||
* Near | ---- ----
|
||||
* Far | ---- ----
|
||||
* VeryFar | -- ---- ----
|
||||
*/
|
||||
Simulator::Schedule (MilliSeconds (301),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar, this);
|
||||
Simulator::Schedule (MilliSeconds (401),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear, this);
|
||||
Simulator::Schedule (MilliSeconds (601),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar, this);
|
||||
Simulator::Schedule (MilliSeconds (801),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear, this);
|
||||
Simulator::Schedule (MilliSeconds (1001),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportNear, this);
|
||||
Simulator::Schedule (MilliSeconds (1201),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportFar, this);
|
||||
Simulator::Schedule (MilliSeconds (1401),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar, this);
|
||||
Simulator::Schedule (MilliSeconds (1601),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportFar, this);
|
||||
Simulator::Schedule (MilliSeconds (1801),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportNear, this);
|
||||
Simulator::Schedule (MilliSeconds (2001),
|
||||
&LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear, this);
|
||||
|
||||
// Run simulation
|
||||
Simulator::Stop (Seconds (2.201));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
} // end of void LteUeMeasurementsPiecewiseTestCase2::DoRun ()
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase2::DoTeardown ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
|
||||
NS_TEST_ASSERT_MSG_EQ (hasEnded, true,
|
||||
"Reporting should have occurred at " << m_itExpectedTime->GetSeconds () << "s");
|
||||
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
|
||||
NS_ASSERT (hasEnded);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback (
|
||||
std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << context);
|
||||
NS_ASSERT (rnti == 1);
|
||||
NS_ASSERT (cellId == 1);
|
||||
|
||||
// verifying the report completeness
|
||||
LteRrcSap::MeasResults measResults = report.measResults;
|
||||
NS_TEST_ASSERT_MSG_EQ (measResults.measId, 1,
|
||||
"Unexpected measurement identity");
|
||||
double rsrpDbm = EutranMeasurementMapping::RsrpRange2Dbm (measResults.rsrpResult);
|
||||
double rsrqDb = EutranMeasurementMapping::RsrqRange2Db (measResults.rsrqResult);
|
||||
NS_LOG_DEBUG (this << " Serving cellId=" << cellId
|
||||
<< " rsrp=" << (uint16_t) measResults.rsrpResult
|
||||
<< " (" << rsrpDbm << " dBm)"
|
||||
<< " rsrq=" << (uint16_t) measResults.rsrqResult
|
||||
<< " (" << rsrqDb << " dB)");
|
||||
NS_TEST_ASSERT_MSG_EQ (measResults.haveMeasResultNeighCells, true,
|
||||
"Report does not have neighboring cells information");
|
||||
|
||||
// verifying reported best cells
|
||||
if (measResults.measResultListEutra.size () == 1)
|
||||
{
|
||||
std::list<LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
|
||||
NS_ASSERT (it != measResults.measResultListEutra.end ());
|
||||
NS_ASSERT (it->physCellId == 2);
|
||||
NS_TEST_ASSERT_MSG_EQ (it->haveCgiInfo, false,
|
||||
"Report contains cgi-info, which is not supported");
|
||||
NS_TEST_ASSERT_MSG_EQ (it->haveRsrpResult, true,
|
||||
"Report does not contain measured RSRP result");
|
||||
NS_TEST_ASSERT_MSG_EQ (it->haveRsrqResult, true,
|
||||
"Report does not contain measured RSRQ result");
|
||||
rsrpDbm = EutranMeasurementMapping::RsrpRange2Dbm (it->rsrpResult);
|
||||
rsrqDb = EutranMeasurementMapping::RsrqRange2Db (it->rsrqResult);
|
||||
NS_LOG_DEBUG (this << " Neighbour cellId=" << it->physCellId
|
||||
<< " rsrp=" << (uint16_t) it->rsrpResult
|
||||
<< " (" << rsrpDbm << " dBm)"
|
||||
<< " rsrq=" << (uint16_t) it->rsrqResult
|
||||
<< " (" << rsrqDb << " dB)");
|
||||
}
|
||||
|
||||
// verifying the report timing
|
||||
bool hasEnded = m_itExpectedTime == m_expectedTime.end ();
|
||||
NS_TEST_ASSERT_MSG_EQ (hasEnded, false,
|
||||
"Reporting should not have occurred at "
|
||||
<< Simulator::Now ().GetSeconds () << "s");
|
||||
if (!hasEnded)
|
||||
{
|
||||
// comparison with milliseconds to avoid floating-point comparison
|
||||
uint64_t timeNowMs = Simulator::Now ().GetMilliSeconds ();
|
||||
uint64_t timeExpectedMs = m_itExpectedTime->GetMilliSeconds ();
|
||||
NS_TEST_ASSERT_MSG_EQ (timeNowMs, timeExpectedMs,
|
||||
"Reporting should not have occurred at this time");
|
||||
m_itExpectedTime++;
|
||||
|
||||
// verifying the report RSRP content
|
||||
hasEnded = m_itExpectedRsrp == m_expectedRsrp.end ();
|
||||
NS_ASSERT (!hasEnded);
|
||||
uint16_t observedRsrp = measResults.rsrpResult;
|
||||
uint16_t referenceRsrp = *m_itExpectedRsrp;
|
||||
NS_TEST_ASSERT_MSG_EQ (observedRsrp, referenceRsrp,
|
||||
"The RSRP observed differs with the reference RSRP");
|
||||
m_itExpectedRsrp++;
|
||||
}
|
||||
|
||||
} // end of void LteUeMeasurementsPiecewiseTestCase2::RecvMeasurementReportCallback
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase2::TeleportVeryNear ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (50.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase2::TeleportNear ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (250.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase2::TeleportFar ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (350.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteUeMeasurementsPiecewiseTestCase2::TeleportVeryFar ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_ueMobility->SetPosition (Vector (550.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace ns3
|
||||
130
src/lte/test/lte-test-ue-measurements-piecewise-2.h
Normal file
130
src/lte/test/lte-test-ue-measurements-piecewise-2.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013 Magister Solutions
|
||||
*
|
||||
* 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: Budiarto Herman <budiarto.herman@magister.fi>
|
||||
*/
|
||||
|
||||
#ifndef LTE_TEST_UE_MEASUREMENTS_PIECEWISE_2_H
|
||||
#define LTE_TEST_UE_MEASUREMENTS_PIECEWISE_2_H
|
||||
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/ptr.h>
|
||||
#include <ns3/lte-rrc-sap.h>
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class MobilityModel;
|
||||
class Time;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test suite for generating calls to UE measurements test case
|
||||
* ns3::LteUeMeasurementsPiecewiseTestCase2.
|
||||
*/
|
||||
class LteUeMeasurementsPiecewiseTestSuite2 : public TestSuite
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsPiecewiseTestSuite2 ();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in
|
||||
* piecewise configuration and 240 ms report interval.
|
||||
*/
|
||||
class LteUeMeasurementsPiecewiseTestCase2 : public TestCase
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsPiecewiseTestCase2 (std::string name,
|
||||
LteRrcSap::ReportConfigEutra config,
|
||||
std::vector<Time> expectedTime,
|
||||
std::vector<uint8_t> expectedRsrp);
|
||||
|
||||
virtual ~LteUeMeasurementsPiecewiseTestCase2 ();
|
||||
|
||||
/**
|
||||
* \brief Triggers when eNodeB receives measurement report from UE, then
|
||||
* perform verification on it.
|
||||
*
|
||||
* The trigger is set up beforehand by connecting to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*
|
||||
* Verification consists of checking whether the report carries the right
|
||||
* value of RSRP or not, and whether it occurs at the expected time or not.
|
||||
*/
|
||||
void RecvMeasurementReportCallback (std::string context, uint64_t imsi,
|
||||
uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Setup the simulation with the intended UE measurement reporting
|
||||
* configuration, run it, and connect the
|
||||
* `RecvMeasurementReportCallback` function to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*/
|
||||
virtual void DoRun ();
|
||||
|
||||
/**
|
||||
* \brief Runs at the end of the simulation, verifying that all expected
|
||||
* measurement reports have been examined.
|
||||
*/
|
||||
virtual void DoTeardown ();
|
||||
|
||||
void TeleportVeryNear ();
|
||||
void TeleportNear ();
|
||||
void TeleportFar ();
|
||||
void TeleportVeryFar ();
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_config;
|
||||
|
||||
/**
|
||||
* \brief The list of expected time when measurement reports are received by
|
||||
* eNodeB.
|
||||
*/
|
||||
std::vector<Time> m_expectedTime;
|
||||
|
||||
/**
|
||||
* \brief The list of expected values of RSRP (in 3GPP range unit) from the
|
||||
* measurement reports received.
|
||||
*/
|
||||
std::vector<uint8_t> m_expectedRsrp;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedTime` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<Time>::iterator m_itExpectedTime;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedRsrp` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<uint8_t>::iterator m_itExpectedRsrp;
|
||||
|
||||
Ptr<MobilityModel> m_ueMobility;
|
||||
|
||||
}; // end of class LteUeMeasurementsPiecewiseTestCase2
|
||||
|
||||
|
||||
} // end of namespace ns3
|
||||
|
||||
#endif /* LTE_TEST_UE_MEASUREMENTS_PIECEWISE_2_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,8 +26,6 @@
|
||||
|
||||
#include <ns3/test.h>
|
||||
#include <ns3/lte-rrc-sap.h>
|
||||
#include <ns3/nstime.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
@@ -41,10 +39,6 @@ class LteUeMeasurementsTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsTestSuite ();
|
||||
void RunOriginalTestCase ();
|
||||
void RunPiecewiseTestCase1 ();
|
||||
void RunPiecewiseTestCase2 ();
|
||||
void RunHandoverTestCase ();
|
||||
};
|
||||
|
||||
|
||||
@@ -72,254 +66,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Testing UE measurements in LTE with simulation of 1 eNodeB and 1 UE in
|
||||
* piecewise configuration and 120 ms report interval.
|
||||
*/
|
||||
class LteUeMeasurementsPiecewiseTestCase1 : public TestCase
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsPiecewiseTestCase1 (std::string name,
|
||||
LteRrcSap::ReportConfigEutra config,
|
||||
std::vector<Time> expectedTime,
|
||||
std::vector<uint8_t> expectedRsrp);
|
||||
|
||||
virtual ~LteUeMeasurementsPiecewiseTestCase1 ();
|
||||
|
||||
/**
|
||||
* \brief Triggers when eNodeB receives measurement report from UE, then
|
||||
* perform verification on it.
|
||||
*
|
||||
* The trigger is set up beforehand by connecting to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*
|
||||
* Verification consists of checking whether the report carries the right
|
||||
* value of RSRP or not, and whether it occurs at the expected time or not.
|
||||
*/
|
||||
void RecvMeasurementReportCallback (std::string context, uint64_t imsi,
|
||||
uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Setup the simulation with the intended UE measurement reporting
|
||||
* configuration, run it, and connect the
|
||||
* `RecvMeasurementReportCallback` function to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*/
|
||||
virtual void DoRun ();
|
||||
|
||||
/**
|
||||
* \brief Runs at the end of the simulation, verifying that all expected
|
||||
* measurement reports have been examined.
|
||||
*/
|
||||
virtual void DoTeardown ();
|
||||
|
||||
void TeleportVeryNear ();
|
||||
void TeleportNear ();
|
||||
void TeleportFar ();
|
||||
void TeleportVeryFar ();
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_config;
|
||||
|
||||
/**
|
||||
* \brief The list of expected time when measurement reports are received by
|
||||
* eNodeB.
|
||||
*/
|
||||
std::vector<Time> m_expectedTime;
|
||||
|
||||
/**
|
||||
* \brief The list of expected values of RSRP (in 3GPP range unit) from the
|
||||
* measurement reports received.
|
||||
*/
|
||||
std::vector<uint8_t> m_expectedRsrp;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedTime` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<Time>::iterator m_itExpectedTime;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedRsrp` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<uint8_t>::iterator m_itExpectedRsrp;
|
||||
|
||||
Ptr<MobilityModel> m_ueMobility;
|
||||
|
||||
}; // end of class LteUeMeasurementsPiecewiseTestCase1
|
||||
|
||||
|
||||
/**
|
||||
* \brief Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in
|
||||
* piecewise configuration and 240 ms report interval.
|
||||
*/
|
||||
class LteUeMeasurementsPiecewiseTestCase2 : public TestCase
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsPiecewiseTestCase2 (std::string name,
|
||||
LteRrcSap::ReportConfigEutra config,
|
||||
std::vector<Time> expectedTime,
|
||||
std::vector<uint8_t> expectedRsrp);
|
||||
|
||||
virtual ~LteUeMeasurementsPiecewiseTestCase2 ();
|
||||
|
||||
/**
|
||||
* \brief Triggers when eNodeB receives measurement report from UE, then
|
||||
* perform verification on it.
|
||||
*
|
||||
* The trigger is set up beforehand by connecting to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*
|
||||
* Verification consists of checking whether the report carries the right
|
||||
* value of RSRP or not, and whether it occurs at the expected time or not.
|
||||
*/
|
||||
void RecvMeasurementReportCallback (std::string context, uint64_t imsi,
|
||||
uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Setup the simulation with the intended UE measurement reporting
|
||||
* configuration, run it, and connect the
|
||||
* `RecvMeasurementReportCallback` function to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*/
|
||||
virtual void DoRun ();
|
||||
|
||||
/**
|
||||
* \brief Runs at the end of the simulation, verifying that all expected
|
||||
* measurement reports have been examined.
|
||||
*/
|
||||
virtual void DoTeardown ();
|
||||
|
||||
void TeleportVeryNear ();
|
||||
void TeleportNear ();
|
||||
void TeleportFar ();
|
||||
void TeleportVeryFar ();
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_config;
|
||||
|
||||
/**
|
||||
* \brief The list of expected time when measurement reports are received by
|
||||
* eNodeB.
|
||||
*/
|
||||
std::vector<Time> m_expectedTime;
|
||||
|
||||
/**
|
||||
* \brief The list of expected values of RSRP (in 3GPP range unit) from the
|
||||
* measurement reports received.
|
||||
*/
|
||||
std::vector<uint8_t> m_expectedRsrp;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedTime` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<Time>::iterator m_itExpectedTime;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedRsrp` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<uint8_t>::iterator m_itExpectedRsrp;
|
||||
|
||||
Ptr<MobilityModel> m_ueMobility;
|
||||
|
||||
}; // end of class LteUeMeasurementsPiecewiseTestCase2
|
||||
|
||||
|
||||
/**
|
||||
* \brief Testing UE measurements in LTE with simulation of 2 eNodeB and 1 UE in
|
||||
* a handover configuration.
|
||||
*
|
||||
* The simulation will run for 2 seconds, while the handover command will be
|
||||
* issued at second +1s.
|
||||
*/
|
||||
class LteUeMeasurementsHandoverTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
LteUeMeasurementsHandoverTestCase (std::string name,
|
||||
LteRrcSap::ReportConfigEutra sourceConfig,
|
||||
LteRrcSap::ReportConfigEutra targetConfig,
|
||||
std::vector<Time> expectedTime,
|
||||
std::vector<uint8_t> expectedRsrp);
|
||||
|
||||
virtual ~LteUeMeasurementsHandoverTestCase ();
|
||||
|
||||
/**
|
||||
* \brief Triggers when either one of the eNodeBs receives measurement report
|
||||
* from UE, then perform verification on it.
|
||||
*
|
||||
* The trigger is set up beforehand by connecting to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*
|
||||
* Verification consists of checking whether the report carries the right
|
||||
* value of RSRP or not, and whether it occurs at the expected time or not.
|
||||
*/
|
||||
void RecvMeasurementReportCallback (std::string context, uint64_t imsi,
|
||||
uint16_t cellId, uint16_t rnti,
|
||||
LteRrcSap::MeasurementReport report);
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Setup the simulation with the intended UE measurement reporting
|
||||
* configuration, run it, and connect the
|
||||
* `RecvMeasurementReportCallback` function to the
|
||||
* `LteUeRrc::RecvMeasurementReport` trace source.
|
||||
*/
|
||||
virtual void DoRun ();
|
||||
|
||||
/**
|
||||
* \brief Runs at the end of the simulation, verifying that all expected
|
||||
* measurement reports have been examined.
|
||||
*/
|
||||
virtual void DoTeardown ();
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration for the source eNodeB.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_sourceConfig;
|
||||
|
||||
/**
|
||||
* \brief The active report triggering configuration for the target eNodeB.
|
||||
*/
|
||||
LteRrcSap::ReportConfigEutra m_targetConfig;
|
||||
|
||||
/**
|
||||
* \brief The list of expected time when measurement reports are received by
|
||||
* eNodeB.
|
||||
*/
|
||||
std::vector<Time> m_expectedTime;
|
||||
|
||||
/**
|
||||
* \brief The list of expected values of RSRP (in 3GPP range unit) from the
|
||||
* measurement reports received.
|
||||
*/
|
||||
std::vector<uint8_t> m_expectedRsrp;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedTime` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<Time>::iterator m_itExpectedTime;
|
||||
|
||||
/**
|
||||
* \brief Pointer to the element of `m_expectedRsrp` which is expected to
|
||||
* occur next in the simulation.
|
||||
*/
|
||||
std::vector<uint8_t>::iterator m_itExpectedRsrp;
|
||||
|
||||
}; // end of class LteUeMeasurementsHandoverTestCase
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
|
||||
@@ -142,6 +142,9 @@ def build(bld):
|
||||
'test/test-lte-x2-handover-measures.cc',
|
||||
'test/test-asn1-encoding.cc',
|
||||
'test/lte-test-ue-measurements.cc',
|
||||
#'test/lte-test-ue-measurements-piecewise-1.cc',
|
||||
#'test/lte-test-ue-measurements-piecewise-2.cc',
|
||||
'test/lte-test-ue-measurements-handover.cc',
|
||||
'test/test-lte-handover-delay.cc',
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user