1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Marco Miozzo <marco.miozzo@cttc.es>
19  */
20 
21 #include <iostream>
22 #include <sstream>
23 #include <string>
24 #include <ns3/object.h>
25 #include <ns3/spectrum-interference.h>
26 #include <ns3/spectrum-error-model.h>
27 #include <ns3/log.h>
28 #include <ns3/test.h>
29 #include <ns3/simulator.h>
30 #include <ns3/packet.h>
31 #include <ns3/ptr.h>
32 #include "ns3/radio-bearer-stats-calculator.h"
33 #include <ns3/mobility-building-info.h>
34 #include <ns3/buildings-propagation-loss-model.h>
35 #include <ns3/eps-bearer.h>
36 #include <ns3/node-container.h>
37 #include <ns3/mobility-helper.h>
38 #include <ns3/net-device-container.h>
39 #include <ns3/lte-ue-net-device.h>
40 #include <ns3/lte-enb-net-device.h>
41 #include <ns3/lte-ue-rrc.h>
42 #include <ns3/lte-helper.h>
43 #include "ns3/string.h"
44 #include "ns3/double.h"
45 #include <ns3/lte-enb-phy.h>
46 #include <ns3/lte-ue-phy.h>
47 #include <ns3/boolean.h>
48 #include <ns3/rr-ff-mac-scheduler.h>
49 #include <ns3/pf-ff-mac-scheduler.h>
50 #include <ns3/pointer.h>
51 #include <ns3/enum.h>
52 #include <ns3/buildings-helper.h>
53 #include "lte-test-mimo.h"
54 
55 
56 using namespace ns3;
57 
58 NS_LOG_COMPONENT_DEFINE ("LteTestMimo");
59 
LenaTestMimoSuite()60 LenaTestMimoSuite::LenaTestMimoSuite ()
61   : TestSuite ("lte-mimo", SYSTEM)
62 {
63   NS_LOG_INFO ("creating LenaMimoTestCase");
64 
65   // RR DOWNLINK- DISTANCE 300
66   // interval 1 : [0.1, 0.2) sec TxMode 0: MCS 20 -> TB size 1191 bytes
67   // interval 2 : [0.3, 0.4) sec TxMode 1: MCS 26 -> TB size 1836 bytes
68   // interval 3 : [0.5, 0.6) sec TxMode 2: MCS 18 -> TB size  967 bytes (x2 layers)
69   // -->
70   std::vector<uint32_t> estThrDl;
71   estThrDl.push_back (119100); // interval 1 : estimated throughput for TxMode 1
72   estThrDl.push_back (183600); // interval 2 : estimated throughput for TxMode 2
73   estThrDl.push_back (193400); // interval 3 : estimated throughput for TxMode 3
74   AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::RrFfMacScheduler", true), TestCase::QUICK);
75   AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::PfFfMacScheduler", true), TestCase::QUICK);
76   AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::RrFfMacScheduler", false), TestCase::QUICK);
77   AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::PfFfMacScheduler", false), TestCase::QUICK);
78 
79 }
80 
81 static LenaTestMimoSuite lenaTestMimoSuite;
82 
83 std::string
BuildNameString(uint16_t dist,std::string schedulerType,bool useIdealRrc)84 LenaMimoTestCase::BuildNameString (uint16_t dist, std::string schedulerType, bool useIdealRrc)
85 {
86   std::ostringstream oss;
87   oss << " UE distance " << dist << " m" << " Scheduler " << schedulerType;
88   if (useIdealRrc)
89     {
90       oss << ", ideal RRC";
91     }
92   else
93     {
94       oss << ", real RRC";
95     }
96   return oss.str ();
97 }
98 
LenaMimoTestCase(uint16_t dist,std::vector<uint32_t> estThrDl,std::string schedulerType,bool useIdealRrc)99 LenaMimoTestCase::LenaMimoTestCase (uint16_t dist, std::vector<uint32_t> estThrDl, std::string schedulerType, bool useIdealRrc)
100   : TestCase (BuildNameString (dist, schedulerType, useIdealRrc)),
101     m_dist (dist),
102     m_estThrDl (estThrDl),
103     m_schedulerType (schedulerType),
104     m_useIdealRrc (useIdealRrc)
105 {
106 }
107 
~LenaMimoTestCase()108 LenaMimoTestCase::~LenaMimoTestCase ()
109 {
110 }
111 
112 void
DoRun(void)113 LenaMimoTestCase::DoRun (void)
114 {
115   NS_LOG_FUNCTION (this << GetName ());
116   Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
117   Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
118   Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (m_useIdealRrc));
119   Config::SetDefault ("ns3::MacStatsCalculator::DlOutputFilename", StringValue (CreateTempDirFilename ("DlMacStats.txt")));
120   Config::SetDefault ("ns3::MacStatsCalculator::UlOutputFilename", StringValue (CreateTempDirFilename ("UlMacStats.txt")));
121   Config::SetDefault ("ns3::RadioBearerStatsCalculator::DlRlcOutputFilename", StringValue (CreateTempDirFilename ("DlRlcStats.txt")));
122   Config::SetDefault ("ns3::RadioBearerStatsCalculator::UlRlcOutputFilename", StringValue (CreateTempDirFilename ("UlRlcStats.txt")));
123 
124   //Disable Uplink Power Control
125   Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
126 
127   /**
128    * Initialize Simulation Scenario: 1 eNB and m_nUser UEs
129    */
130 
131 
132   Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
133   Config::SetDefault ("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue (false));
134   Config::SetDefault ("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue (false));
135 
136 //   lteHelper->SetSchedulerAttribute ("HarqEnabled", BooleanValue (false));
137 
138 
139   lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
140   lteHelper->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (0.0));
141   lteHelper->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (0.0));
142   lteHelper->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0.0));
143 
144 //   lteHelper->EnableLogComponents ();
145 
146   // Create Nodes: eNodeB and UE
147   NodeContainer enbNodes;
148   NodeContainer ueNodes;
149   enbNodes.Create (1);
150   ueNodes.Create (1);
151 
152   // Install Mobility Model
153   MobilityHelper mobility;
154   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
155   mobility.Install (enbNodes);
156   BuildingsHelper::Install (enbNodes);
157   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
158   mobility.Install (ueNodes);
159   BuildingsHelper::Install (ueNodes);
160 
161   // Create Devices and install them in the Nodes (eNB and UE)
162   NetDeviceContainer enbDevs;
163   NetDeviceContainer ueDevs;
164   lteHelper->SetSchedulerType (m_schedulerType);
165   enbDevs = lteHelper->InstallEnbDevice (enbNodes);
166   ueDevs = lteHelper->InstallUeDevice (ueNodes);
167 
168   // Attach a UE to a eNB
169   lteHelper->Attach (ueDevs, enbDevs.Get (0));
170 
171   // Activate an EPS bearer
172   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
173   EpsBearer bearer (q);
174   lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
175 
176 
177   Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
178   Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
179   enbPhy->SetAttribute ("TxPower", DoubleValue (46.0));
180   enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
181   Ptr<MobilityModel> mmenb = enbNodes.Get (0)->GetObject<MobilityModel> ();
182   mmenb->SetPosition (Vector (0.0, 0.0, 30.0));
183 
184   // Set UE's position and power
185   Ptr<MobilityModel> mmue = ueNodes.Get (0)->GetObject<MobilityModel> ();
186   mmue->SetPosition (Vector (m_dist, 0.0, 1.0));
187   Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (0)->GetObject<LteUeNetDevice> ();
188   Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
189   uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
190   uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
191 
192   // need to allow for RRC connection establishment + SRS before enabling traces
193   lteHelper->EnableRlcTraces ();
194   lteHelper->EnableMacTraces ();
195   double simulationTime = 0.6;
196   double tolerance = 0.1;
197 
198   uint8_t rnti = 1;
199   Ptr<LteEnbNetDevice> enbNetDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
200 
201   PointerValue ptrval;
202   enbNetDev->GetCcMap()[0]->GetAttribute ("FfMacScheduler", ptrval);
203   Ptr<PfFfMacScheduler> pfsched;
204   Ptr<RrFfMacScheduler> rrsched;
205   if (m_schedulerType.compare ("ns3::RrFfMacScheduler") == 0)
206     {
207       rrsched = ptrval.Get<RrFfMacScheduler> ();
208       if (rrsched == 0)
209         {
210           NS_FATAL_ERROR ("No RR Scheduler available");
211         }
212       Simulator::Schedule (Seconds (0.2), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 1);
213       Simulator::Schedule (Seconds (0.4), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 2);
214     }
215   else if (m_schedulerType.compare ("ns3::PfFfMacScheduler") == 0)
216     {
217       pfsched = ptrval.Get<PfFfMacScheduler> ();
218       if (pfsched == 0)
219         {
220           NS_FATAL_ERROR ("No Pf Scheduler available");
221         }
222 
223       Simulator::Schedule (Seconds (0.2), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 1);
224       Simulator::Schedule (Seconds (0.4), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 2);
225     }
226   else
227     {
228       NS_FATAL_ERROR ("Scheduler not supported by this test");
229     }
230 
231 
232   Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
233   rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.1)));
234 
235   NS_LOG_INFO (m_schedulerType << " MIMO test:");
236   double sampleTime = 0.199999; // at 0.2 RlcStats are reset
237   for (uint8_t j = 0; j < m_estThrDl.size (); j ++)
238     {
239       NS_LOG_INFO ("\t test with user at distance " << m_dist << " time " << sampleTime);
240       // get the imsi
241       uint64_t imsi = ueDevs.Get (0)->GetObject<LteUeNetDevice> ()->GetImsi ();
242       uint8_t lcId = 3;
243       Time t = Seconds (sampleTime);
244       Simulator::Schedule(t, &LenaMimoTestCase::GetRlcBufferSample, this, rlcStats, imsi, lcId);
245       sampleTime += 0.2;
246     }
247   Simulator::Stop (Seconds (simulationTime));
248   Simulator::Run ();
249   Simulator::Destroy ();
250 
251   NS_LOG_INFO ("Check consistency");
252     for (uint8_t i = 0; i < m_estThrDl.size (); i++)
253       {
254         NS_LOG_INFO ("interval " << i + 1 << ": bytes rxed " << (double)m_dlDataRxed.at (i) << " ref " << m_estThrDl.at (i));
255         NS_TEST_ASSERT_MSG_EQ_TOL ((double)m_dlDataRxed.at (i) , m_estThrDl.at (i), m_estThrDl.at (i) * tolerance, " Unfair Throughput!");
256       }
257 
258 }
259 
260 
261 void
GetRlcBufferSample(Ptr<RadioBearerStatsCalculator> rlcStats,uint64_t imsi,uint8_t lcId)262 LenaMimoTestCase::GetRlcBufferSample (Ptr<RadioBearerStatsCalculator> rlcStats, uint64_t imsi, uint8_t lcId)
263 {
264   m_dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
265   NS_LOG_INFO (Simulator::Now () << "\t get bytes " << m_dlDataRxed.at (m_dlDataRxed.size () - 1));
266 }
267