Split UE measurements tests into multiple test suites (still problem with operator redefinition)

This commit is contained in:
Budiarto Herman
2013-07-03 14:09:58 +03:00
parent 8a8559d63c
commit a0b74cea40
9 changed files with 1873 additions and 1509 deletions

View 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

View 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 */

View 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

View 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 */

View 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

View 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

View File

@@ -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

View File

@@ -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',
]