From 6c96b91ddcb56e672d9712a7d902bf821200688d Mon Sep 17 00:00:00 2001 From: Biljana Bojovic Date: Thu, 2 Feb 2017 10:02:12 +0100 Subject: [PATCH] lte: add carrier aggregation test files --- src/lte/test/lte-test-carrier-aggregation.cc | 478 +++++++++++++++++++ src/lte/test/lte-test-carrier-aggregation.h | 82 ++++ 2 files changed, 560 insertions(+) create mode 100644 src/lte/test/lte-test-carrier-aggregation.cc create mode 100644 src/lte/test/lte-test-carrier-aggregation.h diff --git a/src/lte/test/lte-test-carrier-aggregation.cc b/src/lte/test/lte-test-carrier-aggregation.cc new file mode 100644 index 000000000..6b3baae71 --- /dev/null +++ b/src/lte/test/lte-test-carrier-aggregation.cc @@ -0,0 +1,478 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2016 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Biljana Bojovic + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ns3/radio-bearer-stats-calculator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ns3/string.h" +#include "ns3/double.h" +#include +#include +#include +#include +#include +#include + +#include "lte-test-carrier-aggregation.h" + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("TestCarrierAggregation"); + +bool CarrierAggregationTestCase::s_writeResults = false; // set to true to write response vectors +const std::string dlResultsFileName = "carrier_aggregation_results_dl.txt"; +const std::string ulResultsFileName = "carrier_aggregation_results_ul.txt"; + + +void +LteTestDlSchedulingCallback (CarrierAggregationTestCase *testcase, std::string path, DlSchedulingCallbackInfo dlInfo) +{ + testcase->DlScheduling (dlInfo); +} + +void +LteTestUlSchedulingCallback (CarrierAggregationTestCase *testcase, std::string path, + uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, + uint8_t mcs, uint16_t sizeTb, uint8_t ccId) +{ + testcase->UlScheduling (frameNo, subframeNo, rnti, mcs, sizeTb, ccId); +} + + +TestCarrierAggregationSuite::TestCarrierAggregationSuite () + : TestSuite ("lte-carrier-aggregation", SYSTEM) +{ + NS_LOG_INFO ("creating CarrierAggregationTestCase"); + + if (CarrierAggregationTestCase::s_writeResults) // write result vectors to file + { + std::cout<<"\n Running TestCarrierAggregationSuite with activated option to write results to files." + "Dl results will be written to "< lteHelper = CreateObject (); + + lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::FriisSpectrumPropagationLossModel")); + + // Create Nodes: eNodeB and UE + NodeContainer enbNodes; + NodeContainer ueNodes; + enbNodes.Create (1); + ueNodes.Create (m_nUser); + + // Install Mobility Model + MobilityHelper mobility; + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (enbNodes); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (ueNodes); + + // Create Devices and install them in the Nodes (eNB and UE) + NetDeviceContainer enbDevs; + NetDeviceContainer ueDevs; + lteHelper->SetSchedulerType ("ns3::PfFfMacScheduler"); + enbDevs = lteHelper->InstallEnbDevice (enbNodes); + ueDevs = lteHelper->InstallUeDevice (ueNodes); + + // Attach a UE to a eNB + lteHelper->Attach (ueDevs, enbDevs.Get (0)); + + // Activate an EPS bearer + enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; + EpsBearer bearer (q); + lteHelper->ActivateDataRadioBearer (ueDevs, bearer); + + + Ptr lteEnbDev = enbDevs.Get (0)->GetObject (); + Ptr enbPhy = lteEnbDev->GetPhy (); + enbPhy->SetAttribute ("TxPower", DoubleValue (30.0)); + enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0)); + + // Set UEs' position and power + for (int i = 0; i < m_nUser; i++) + { + Ptr mm = ueNodes.Get (i)->GetObject (); + mm->SetPosition (Vector (m_dist, 0.0, 0.0)); + Ptr lteUeDev = ueDevs.Get (i)->GetObject (); + Ptr uePhy = lteUeDev->GetPhy (); + uePhy->SetAttribute ("TxPower", DoubleValue (23.0)); + uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0)); + } + + + double statsStartTime = 0.300; // need to allow for RRC connection establishment + SRS + + Simulator::Stop (Seconds (statsStartTime + m_statsDuration - 0.0001)); + + Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbMac/DlScheduling", + MakeBoundCallback (&LteTestDlSchedulingCallback, this)); + + Config::Connect ("/NodeList/*/DeviceList/*/ComponentCarrierMap/*/LteEnbMac/UlScheduling", + MakeBoundCallback (&LteTestUlSchedulingCallback, this)); + + lteHelper->EnableTraces(); + + Simulator::Run (); + + /** + * Check that the assignation is done in a RR fashion + */ + NS_LOG_INFO ("DL - Test with " << m_nUser << " user(s) at distance " << m_dist); + std::vector dlDataRxed; + + // tolerance increases with the number of users because the lc 0 and lc 1 will go always over primary carrier, so as the number of users increases the difference between primary and secondary + //carrier will increase + + bool testDownlinkShare = true; + + for (std::map ::iterator itDownlink = m_ccDownlinkTraffic.begin(); itDownlink!=m_ccDownlinkTraffic.end(); itDownlink++) + { + + if (itDownlink == m_ccDownlinkTraffic.begin()) + { + NS_LOG_INFO ("Downlink traffic per carrier:"<second); + } + else + { + if (itDownlink->second != m_ccDownlinkTraffic.begin()->second) + { + testDownlinkShare = false; + break; + } + } + } + + bool testUplinkShare = true; + + for (std::map ::iterator itUplink = m_ccUplinkTraffic.begin(); itUplink!=m_ccUplinkTraffic.end(); itUplink++) + { + if (itUplink == m_ccUplinkTraffic.begin()) + { + NS_LOG_INFO ("Uplink traffic per carrier:"<second); + } + else + { + if (itUplink->second != m_ccUplinkTraffic.begin()->second) + { + testUplinkShare = false; + break; + } + } + } + + NS_TEST_ASSERT_MSG_EQ (m_ccUplinkTraffic.size(), m_numberOfComponentCarriers, "Number of carriers in uplink does not correspond to number of carriers being configured in test."); + NS_TEST_ASSERT_MSG_EQ (m_ccDownlinkTraffic.size(), m_numberOfComponentCarriers, "Number of carriers in downlink does not correspond to number of carriers being configured in test."); + + NS_TEST_ASSERT_MSG_EQ (testDownlinkShare, true, " Downlink traffic not split equally between carriers!"); + NS_TEST_ASSERT_MSG_EQ (testUplinkShare, true , " Uplink traffic not split equally between carriers"); + + if (s_writeResults) + WriteResultToFile (); + + Simulator::Destroy (); +} + +void +CarrierAggregationTestCase::DlScheduling (DlSchedulingCallbackInfo dlInfo) +{ + //NS_LOG_FUNCTION (dlInfo.frameNo << dlInfo.subframeNo << dlInfo.rnti << (uint32_t) dlInfo.mcsTb1 << dlInfo.sizeTb1 << (uint32_t) dlInfo.mcsTb2 << dlInfo.sizeTb2<<(uint16_t)dlInfo.componentCarrierId); + // need to allow for RRC connection establishment + CQI feedback reception + persistent data transmission + if (Simulator::Now () > MilliSeconds (300)) + { + if (m_ccDownlinkTraffic.find(dlInfo.componentCarrierId) == m_ccDownlinkTraffic.end()) + { + m_ccDownlinkTraffic.insert (std::pair (dlInfo.componentCarrierId, dlInfo.sizeTb1 + dlInfo.sizeTb2)); + } + else + { + m_ccDownlinkTraffic[dlInfo.componentCarrierId]+= (dlInfo.sizeTb1 + dlInfo.sizeTb2); + } + + m_dlThroughput += dlInfo.sizeTb1 + dlInfo.sizeTb2; + } +} + +void +CarrierAggregationTestCase::UlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, + uint8_t mcs, uint16_t sizeTb, uint8_t componentCarrierId) +{ + //NS_LOG_FUNCTION (frameNo << subframeNo << rnti << (uint32_t) mcs << sizeTb); + // need to allow for RRC connection establishment + SRS transmission + if (Simulator::Now () > MilliSeconds (300)) + { + if (m_ccUplinkTraffic.find(componentCarrierId) == m_ccUplinkTraffic.end()) + { + m_ccUplinkTraffic.insert (std::pair (componentCarrierId, sizeTb)); + } + else + { + m_ccUplinkTraffic[componentCarrierId] += sizeTb; + } + + m_ulThroughput += sizeTb; + } +} + +void +CarrierAggregationTestCase::WriteResultToFile () +{ + std::ofstream dlOutFile; + dlOutFile.open (dlResultsFileName.c_str(), std::ofstream::out | std::ofstream::app); + dlOutFile.setf (std::ios_base::fixed); + + if (!dlOutFile.is_open ()) + { + NS_LOG_ERROR ("Can't open file "< + * + */ + +#ifndef TEST_CARRIER_AGGREGATION_H +#define TEST_CARRIER_AGGREGATION_H + +#include "ns3/simulator.h" +#include "ns3/test.h" +#include "fcntl.h" + + +using namespace ns3; + + +/** + * This system test program creates different test cases with a single eNB and + * several UEs, all having the same Radio Bearer specification. In each test + * case, the UEs see the same SINR from the eNB; different test cases are + * implemented obtained by using different SINR values and different numbers of + * UEs. eNb and UEs are configured to use the secondary carrier and the component + * carrier manager is configured to split the data equally between primary and + * secondary carrier. The test consists of checking that the throughput + * obtained over different carriers are equal within a given tolerance. + */ +class CarrierAggregationTestCase : public TestCase +{ +public: + + static bool s_writeResults; + + CarrierAggregationTestCase (uint16_t nUser, uint16_t dist, uint32_t dlbandwidth, uint32_t ulBandwidth, uint numberOfComponentCarriers); + virtual ~CarrierAggregationTestCase (); + void DlScheduling (DlSchedulingCallbackInfo dlInfo); + void UlScheduling (uint32_t frameNo, uint32_t subframeNo, uint16_t rnti, uint8_t mcs, uint16_t sizeTb, uint8_t componentCarrierId); + void WriteResultToFile (); + + +private: + + virtual void DoRun (void); + static std::string BuildNameString (uint16_t nUser, uint16_t dist, uint32_t dlBandwidth, uint32_t ulBandwidth, uint32_t numberOfComponentCarriers); + + uint16_t m_nUser; + uint16_t m_dist; + uint32_t m_dlBandwidth; + uint32_t m_ulBandwidth; + uint32_t m_numberOfComponentCarriers; + + std::map m_ccDownlinkTraffic; + std::map m_ccUplinkTraffic; + uint64_t m_dlThroughput; + uint64_t m_ulThroughput; + double m_statsDuration; +}; + + + +class TestCarrierAggregationSuite : public TestSuite +{ +public: + TestCarrierAggregationSuite (); +}; + +#endif /* TEST_CARRIER_AGGREGATION_H */