A Discrete-Event Network Simulator
API
epc-test-s1u-downlink.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Nicola Baldo <nbaldo@cttc.es>
18  */
19 
20 #include "lte-test-entities.h"
21 
22 #include "ns3/boolean.h"
23 #include "ns3/config.h"
24 #include "ns3/csma-helper.h"
25 #include "ns3/epc-enb-application.h"
26 #include "ns3/eps-bearer.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/internet-stack-helper.h"
29 #include "ns3/ipv4-address-helper.h"
30 #include "ns3/log.h"
31 #include "ns3/packet-sink-helper.h"
32 #include "ns3/packet-sink.h"
33 #include "ns3/point-to-point-epc-helper.h"
34 #include "ns3/point-to-point-helper.h"
35 #include "ns3/simulator.h"
36 #include "ns3/test.h"
37 #include "ns3/udp-echo-helper.h"
38 #include "ns3/uinteger.h"
39 #include <ns3/ipv4-static-routing-helper.h>
40 #include <ns3/ipv4-static-routing.h>
41 
42 using namespace ns3;
43 
44 NS_LOG_COMPONENT_DEFINE("EpcTestS1uDownlink");
45 
52 {
59  UeDlTestData(uint32_t n, uint32_t s);
60 
61  uint32_t numPkts;
62  uint32_t pktSize;
63 
66 };
67 
68 UeDlTestData::UeDlTestData(uint32_t n, uint32_t s)
69  : numPkts(n),
70  pktSize(s)
71 {
72 }
73 
81 {
82  std::vector<UeDlTestData> ues;
83 };
84 
90 class EpcS1uDlTestCase : public TestCase
91 {
92  public:
99  EpcS1uDlTestCase(std::string name, std::vector<EnbDlTestData> v);
100  ~EpcS1uDlTestCase() override;
101 
102  private:
103  void DoRun() override;
104  std::vector<EnbDlTestData> m_enbDlTestData;
105 };
106 
107 EpcS1uDlTestCase::EpcS1uDlTestCase(std::string name, std::vector<EnbDlTestData> v)
108  : TestCase(name),
109  m_enbDlTestData(v)
110 {
111 }
112 
114 {
115 }
116 
117 void
119 {
120  Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper>();
121  Ptr<Node> pgw = epcHelper->GetPgwNode();
122 
123  // allow jumbo packets
124  Config::SetDefault("ns3::CsmaNetDevice::Mtu", UintegerValue(30000));
125  Config::SetDefault("ns3::PointToPointNetDevice::Mtu", UintegerValue(30000));
126  epcHelper->SetAttribute("S1uLinkMtu", UintegerValue(30000));
127 
128  // Create a single RemoteHost
129  NodeContainer remoteHostContainer;
130  remoteHostContainer.Create(1);
131  Ptr<Node> remoteHost = remoteHostContainer.Get(0);
132  InternetStackHelper internet;
133  internet.Install(remoteHostContainer);
134 
135  // Create the internet
136  PointToPointHelper p2ph;
137  p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
138  NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
139  Ipv4AddressHelper ipv4h;
140  ipv4h.SetBase("1.0.0.0", "255.0.0.0");
141  ipv4h.Assign(internetDevices);
142 
143  // setup default gateway for the remote hosts
144  Ipv4StaticRoutingHelper ipv4RoutingHelper;
145  Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
146  ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
147 
148  // hardcoded UE addresses for now
149  remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
150  Ipv4Mask("255.255.255.0"),
151  1);
152 
153  NodeContainer enbs;
154  uint16_t cellIdCounter = 0;
155  uint64_t imsiCounter = 0;
156 
157  for (std::vector<EnbDlTestData>::iterator enbit = m_enbDlTestData.begin();
158  enbit < m_enbDlTestData.end();
159  ++enbit)
160  {
161  Ptr<Node> enb = CreateObject<Node>();
162  enbs.Add(enb);
163 
164  // we test EPC without LTE, hence we use:
165  // 1) a CSMA network to simulate the cell
166  // 2) a raw socket opened on the CSMA device to simulate the LTE socket
167 
168  uint16_t cellId = ++cellIdCounter;
169 
170  NodeContainer ues;
171  ues.Create(enbit->ues.size());
172 
173  NodeContainer cell;
174  cell.Add(ues);
175  cell.Add(enb);
176 
177  CsmaHelper csmaCell;
178  NetDeviceContainer cellDevices = csmaCell.Install(cell);
179 
180  // the eNB's CSMA NetDevice acting as an LTE NetDevice.
181  Ptr<NetDevice> enbDevice = cellDevices.Get(cellDevices.GetN() - 1);
182 
183  // Note that the EpcEnbApplication won't care of the actual NetDevice type
184  std::vector<uint16_t> cellIds;
185  cellIds.push_back(cellId);
186  epcHelper->AddEnb(enb, enbDevice, cellIds);
187 
188  // Plug test RRC entity
190  NS_ASSERT_MSG(enbApp, "cannot retrieve EpcEnbApplication");
191  Ptr<EpcTestRrc> rrc = CreateObject<EpcTestRrc>();
192  enb->AggregateObject(rrc);
193  rrc->SetS1SapProvider(enbApp->GetS1SapProvider());
194  enbApp->SetS1SapUser(rrc->GetS1SapUser());
195 
196  // we install the IP stack on UEs only
197  InternetStackHelper internet;
198  internet.Install(ues);
199 
200  // assign IP address to UEs, and install applications
201  for (uint32_t u = 0; u < ues.GetN(); ++u)
202  {
203  Ptr<NetDevice> ueLteDevice = cellDevices.Get(u);
204  Ipv4InterfaceContainer ueIpIface =
205  epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueLteDevice));
206 
207  Ptr<Node> ue = ues.Get(u);
208 
209  // disable IP Forwarding on the UE. This is because we use
210  // CSMA broadcast MAC addresses for this test. The problem
211  // won't happen with a LteUeNetDevice.
212  ue->GetObject<Ipv4>()->SetAttribute("IpForward", BooleanValue(false));
213 
214  uint16_t port = 1234;
215  PacketSinkHelper packetSinkHelper("ns3::UdpSocketFactory",
216  InetSocketAddress(Ipv4Address::GetAny(), port));
217  ApplicationContainer apps = packetSinkHelper.Install(ue);
218  apps.Start(Seconds(1.0));
219  apps.Stop(Seconds(10.0));
220  enbit->ues[u].serverApp = apps.Get(0)->GetObject<PacketSink>();
221 
222  Time interPacketInterval = Seconds(0.01);
223  UdpEchoClientHelper client(ueIpIface.GetAddress(0), port);
224  client.SetAttribute("MaxPackets", UintegerValue(enbit->ues[u].numPkts));
225  client.SetAttribute("Interval", TimeValue(interPacketInterval));
226  client.SetAttribute("PacketSize", UintegerValue(enbit->ues[u].pktSize));
227  apps = client.Install(remoteHost);
228  apps.Start(Seconds(2.0));
229  apps.Stop(Seconds(10.0));
230  enbit->ues[u].clientApp = apps.Get(0);
231 
232  uint64_t imsi = ++imsiCounter;
233  epcHelper->AddUe(ueLteDevice, imsi);
234  epcHelper->ActivateEpsBearer(ueLteDevice,
235  imsi,
236  EpcTft::Default(),
237  EpsBearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
238  Simulator::Schedule(MilliSeconds(10),
239  &EpcEnbS1SapProvider::InitialUeMessage,
240  enbApp->GetS1SapProvider(),
241  imsi,
242  (uint16_t)imsi);
243  }
244  }
245 
246  Simulator::Run();
247 
248  for (std::vector<EnbDlTestData>::iterator enbit = m_enbDlTestData.begin();
249  enbit < m_enbDlTestData.end();
250  ++enbit)
251  {
252  for (std::vector<UeDlTestData>::iterator ueit = enbit->ues.begin(); ueit < enbit->ues.end();
253  ++ueit)
254  {
255  NS_TEST_ASSERT_MSG_EQ(ueit->serverApp->GetTotalRx(),
256  (ueit->numPkts) * (ueit->pktSize),
257  "wrong total received bytes");
258  }
259  }
260 
261  Simulator::Destroy();
262 }
263 
268 {
269  public:
271 
273 
275  : TestSuite("epc-s1u-downlink", SYSTEM)
276 {
277  std::vector<EnbDlTestData> v1;
278  EnbDlTestData e1;
279  UeDlTestData f1(1, 100);
280  e1.ues.push_back(f1);
281  v1.push_back(e1);
282  AddTestCase(new EpcS1uDlTestCase("1 eNB, 1UE", v1), TestCase::QUICK);
283 
284  std::vector<EnbDlTestData> v2;
285  EnbDlTestData e2;
286  UeDlTestData f2_1(1, 100);
287  e2.ues.push_back(f2_1);
288  UeDlTestData f2_2(2, 200);
289  e2.ues.push_back(f2_2);
290  v2.push_back(e2);
291  AddTestCase(new EpcS1uDlTestCase("1 eNB, 2UEs", v2), TestCase::QUICK);
292 
293  std::vector<EnbDlTestData> v3;
294  v3.push_back(e1);
295  v3.push_back(e2);
296  AddTestCase(new EpcS1uDlTestCase("2 eNBs", v3), TestCase::QUICK);
297 
298  EnbDlTestData e3;
299  UeDlTestData f3_1(3, 50);
300  e3.ues.push_back(f3_1);
301  UeDlTestData f3_2(5, 1472);
302  e3.ues.push_back(f3_2);
303  UeDlTestData f3_3(1, 1);
304  e3.ues.push_back(f3_2);
305  std::vector<EnbDlTestData> v4;
306  v4.push_back(e3);
307  v4.push_back(e1);
308  v4.push_back(e2);
309  AddTestCase(new EpcS1uDlTestCase("3 eNBs", v4), TestCase::QUICK);
310 
311  std::vector<EnbDlTestData> v5;
312  EnbDlTestData e5;
313  UeDlTestData f5(10, 3000);
314  e5.ues.push_back(f5);
315  v5.push_back(e5);
316  AddTestCase(new EpcS1uDlTestCase("1 eNB, 10 pkts 3000 bytes each", v5), TestCase::QUICK);
317 
318  std::vector<EnbDlTestData> v6;
319  EnbDlTestData e6;
320  UeDlTestData f6(50, 3000);
321  e6.ues.push_back(f6);
322  v6.push_back(e6);
323  AddTestCase(new EpcS1uDlTestCase("1 eNB, 50 pkts 3000 bytes each", v6), TestCase::QUICK);
324 
325  std::vector<EnbDlTestData> v7;
326  EnbDlTestData e7;
327  UeDlTestData f7(10, 15000);
328  e7.ues.push_back(f7);
329  v7.push_back(e7);
330  AddTestCase(new EpcS1uDlTestCase("1 eNB, 10 pkts 15000 bytes each", v7), TestCase::QUICK);
331 
332  std::vector<EnbDlTestData> v8;
333  EnbDlTestData e8;
334  UeDlTestData f8(100, 15000);
335  e8.ues.push_back(f8);
336  v8.push_back(e8);
337  AddTestCase(new EpcS1uDlTestCase("1 eNB, 100 pkts 15000 bytes each", v8), TestCase::QUICK);
338 }
EpcS1uDlTestCase class.
std::vector< EnbDlTestData > m_enbDlTestData
ENB DL test data.
EpcS1uDlTestCase(std::string name, std::vector< EnbDlTestData > v)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Test that the S1-U interface implementation works correctly.
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
build a set of CsmaNetDevice objects
Definition: csma-helper.h:48
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::CsmaChannel with the attributes configured by CsmaHelper::SetChannelAttri...
Definition: csma-helper.cc:226
AttributeValue implementation for DataRate.
This application is installed inside eNBs and provides the bridge functionality for user data plane p...
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
Helper class that adds ns3::Ipv4StaticRouting objects.
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
void AddUe(Ptr< NetDevice > ueLteDevice, uint64_t imsi) override
Notify the EPC of the existence of a new UE which might attach at a later time.
uint8_t ActivateEpsBearer(Ptr< NetDevice > ueLteDevice, uint64_t imsi, Ptr< EpcTft > tft, EpsBearer bearer) override
Activate an EPS bearer, setting up the corresponding S1-U tunnel.
Ptr< Node > GetPgwNode() const override
Get the PGW node.
Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices) override
Assign IPv4 addresses to UE devices.
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< Application > GetApplication(uint32_t index) const
Retrieve the index-th Application associated to this node.
Definition: node.cc:180
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
Receive and consume traffic generated to an IP address and port.
Definition: packet-sink.h:74
void AddEnb(Ptr< Node > enbNode, Ptr< NetDevice > lteEnbNetDevice, std::vector< uint16_t > cellIds) override
Add an eNB to the EPC.
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
NetDeviceContainer Install(NodeContainer c)
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
Create an application which sends a UDP packet and waits for an echo of this packet.
void SetAttribute(std::string name, const AttributeValue &value)
Record an attribute to be set in each Application after it is is created.
ApplicationContainer Install(Ptr< Node > node) const
Create a udp echo client application on the specified node.
Hold an unsigned integer type.
Definition: uinteger.h:45
uint16_t port
Definition: dsdv-manet.cc:45
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Custom structure for testing eNodeB downlink data, contains the list of data structures for UEs.
std::vector< UeDlTestData > ues
list of data structure for different UEs
Custom structure for testing UE downlink data.
uint32_t pktSize
packet size
UeDlTestData(uint32_t n, uint32_t s)
Constructor.
uint32_t numPkts
number of packets
Ptr< Application > clientApp
Client application.
Ptr< PacketSink > serverApp
Server application.
uint32_t pktSize
packet size used for the simulation (in bytes)