1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2007,2008,2009 INRIA, UDCAST
4 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * The original version of UdpClient is by Amine Ismail
20 * <amine.ismail@sophia.inria.fr> <amine.ismail@udcast.com>
21 * The rest of the code (including modifying UdpClient into
22 * EpsBearerTagUdpClient) is by Nicola Baldo <nbaldo@cttc.es>
23 */
24
25
26
27 #include "ns3/simulator.h"
28 #include "ns3/log.h"
29 #include "ns3/test.h"
30 #include "ns3/point-to-point-epc-helper.h"
31 #include "ns3/epc-enb-application.h"
32 #include "ns3/packet-sink-helper.h"
33 #include "ns3/point-to-point-helper.h"
34 #include "ns3/csma-helper.h"
35 #include "ns3/internet-stack-helper.h"
36 #include "ns3/ipv4-address-helper.h"
37 #include "ns3/inet-socket-address.h"
38 #include "ns3/packet-sink.h"
39 #include <ns3/ipv4-static-routing-helper.h>
40 #include <ns3/ipv4-static-routing.h>
41 #include <ns3/ipv4-interface.h>
42 #include <ns3/mac48-address.h>
43 #include "ns3/seq-ts-header.h"
44 #include "ns3/eps-bearer-tag.h"
45 #include "ns3/arp-cache.h"
46 #include "ns3/boolean.h"
47 #include "ns3/uinteger.h"
48 #include "ns3/config.h"
49 #include "lte-test-entities.h"
50
51 using namespace ns3;
52
53 NS_LOG_COMPONENT_DEFINE ("EpcTestS1uUplink");
54
55 /**
56 * \ingroup lte-test
57 * \ingroup tests
58 *
59 * A Udp client. Sends UDP packet carrying sequence number and time
60 * stamp but also including the EpsBearerTag. This tag is normally
61 * generated by the LteEnbNetDevice when forwarding packet in the
62 * uplink. But in this test we don't have the LteEnbNetDevice, because
63 * we test the S1-U interface with simpler devices to make sure it
64 * just works.
65 *
66 */
67 class EpsBearerTagUdpClient : public Application
68 {
69 public:
70 /**
71 * \brief Get the type ID.
72 * \return the object TypeId
73 */
74 static TypeId
75 GetTypeId (void);
76
77 EpsBearerTagUdpClient ();
78 /**
79 * Constructor
80 *
81 * \param rnti the RNTI
82 * \param bid the BID
83 */
84 EpsBearerTagUdpClient (uint16_t rnti, uint8_t bid);
85
86 virtual ~EpsBearerTagUdpClient ();
87
88 /**
89 * \brief set the remote address and port
90 * \param ip remote IP address
91 * \param port remote port
92 */
93 void SetRemote (Ipv4Address ip, uint16_t port);
94
95 protected:
96 virtual void DoDispose (void);
97
98 private:
99 virtual void StartApplication (void);
100 virtual void StopApplication (void);
101
102 /**
103 * \brief Schedule transmit function
104 * \param dt the delta time
105 */
106 void ScheduleTransmit (Time dt);
107 /// Send function
108 void Send (void);
109
110 uint32_t m_count; ///< maximum number of packets to send
111 Time m_interval; ///< the time between packets
112 uint32_t m_size; ///< the size of packets generated
113
114 uint32_t m_sent; ///< number of packets sent
115 Ptr<Socket> m_socket; ///< the socket
116 Ipv4Address m_peerAddress; ///< the peer address of the outbound packets
117 uint16_t m_peerPort; ///< the destination port of the outbound packets
118 EventId m_sendEvent; ///< the send event
119
120 uint16_t m_rnti; ///< the RNTI
121 uint8_t m_bid; ///< the bearer identificator
122
123 };
124
125
126
127 TypeId
GetTypeId(void)128 EpsBearerTagUdpClient::GetTypeId (void)
129 {
130 static TypeId tid = TypeId ("ns3::EpsBearerTagUdpClient")
131 .SetParent<Application> ()
132 .AddConstructor<EpsBearerTagUdpClient> ()
133 .AddAttribute ("MaxPackets",
134 "The maximum number of packets the application will send",
135 UintegerValue (100),
136 MakeUintegerAccessor (&EpsBearerTagUdpClient::m_count),
137 MakeUintegerChecker<uint32_t> ())
138 .AddAttribute ("Interval",
139 "The time to wait between packets", TimeValue (Seconds (1.0)),
140 MakeTimeAccessor (&EpsBearerTagUdpClient::m_interval),
141 MakeTimeChecker ())
142 .AddAttribute ("RemoteAddress",
143 "The destination Ipv4Address of the outbound packets",
144 Ipv4AddressValue (),
145 MakeIpv4AddressAccessor (&EpsBearerTagUdpClient::m_peerAddress),
146 MakeIpv4AddressChecker ())
147 .AddAttribute ("RemotePort", "The destination port of the outbound packets",
148 UintegerValue (100),
149 MakeUintegerAccessor (&EpsBearerTagUdpClient::m_peerPort),
150 MakeUintegerChecker<uint16_t> ())
151 .AddAttribute ("PacketSize",
152 "Size of packets generated. The minimum packet size is 12 bytes which is the size of the header carrying the sequence number and the time stamp.",
153 UintegerValue (1024),
154 MakeUintegerAccessor (&EpsBearerTagUdpClient::m_size),
155 MakeUintegerChecker<uint32_t> ())
156 ;
157 return tid;
158 }
159
EpsBearerTagUdpClient()160 EpsBearerTagUdpClient::EpsBearerTagUdpClient ()
161 : m_rnti (0),
162 m_bid (0)
163 {
164 NS_LOG_FUNCTION_NOARGS ();
165 m_sent = 0;
166 m_socket = 0;
167 m_sendEvent = EventId ();
168 }
169
EpsBearerTagUdpClient(uint16_t rnti,uint8_t bid)170 EpsBearerTagUdpClient::EpsBearerTagUdpClient (uint16_t rnti, uint8_t bid)
171 : m_rnti (rnti),
172 m_bid (bid)
173 {
174 NS_LOG_FUNCTION_NOARGS ();
175 m_sent = 0;
176 m_socket = 0;
177 m_sendEvent = EventId ();
178 }
179
~EpsBearerTagUdpClient()180 EpsBearerTagUdpClient::~EpsBearerTagUdpClient ()
181 {
182 NS_LOG_FUNCTION_NOARGS ();
183 }
184
185 void
SetRemote(Ipv4Address ip,uint16_t port)186 EpsBearerTagUdpClient::SetRemote (Ipv4Address ip, uint16_t port)
187 {
188 m_peerAddress = ip;
189 m_peerPort = port;
190 }
191
192 void
DoDispose(void)193 EpsBearerTagUdpClient::DoDispose (void)
194 {
195 NS_LOG_FUNCTION_NOARGS ();
196 Application::DoDispose ();
197 }
198
199 void
StartApplication(void)200 EpsBearerTagUdpClient::StartApplication (void)
201 {
202 NS_LOG_FUNCTION_NOARGS ();
203
204 if (m_socket == 0)
205 {
206 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
207 m_socket = Socket::CreateSocket (GetNode (), tid);
208 m_socket->Bind ();
209 m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
210 }
211
212 m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
213 m_sendEvent = Simulator::Schedule (Seconds (0.0), &EpsBearerTagUdpClient::Send, this);
214 }
215
216 void
StopApplication()217 EpsBearerTagUdpClient::StopApplication ()
218 {
219 NS_LOG_FUNCTION_NOARGS ();
220 Simulator::Cancel (m_sendEvent);
221 }
222
223 void
Send(void)224 EpsBearerTagUdpClient::Send (void)
225 {
226 NS_LOG_FUNCTION_NOARGS ();
227 NS_ASSERT (m_sendEvent.IsExpired ());
228 SeqTsHeader seqTs;
229 seqTs.SetSeq (m_sent);
230 Ptr<Packet> p = Create<Packet> (m_size - (8 + 4)); // 8+4 : the size of the seqTs header
231 p->AddHeader (seqTs);
232
233 EpsBearerTag tag (m_rnti, m_bid);
234 p->AddPacketTag (tag);
235
236 if ((m_socket->Send (p)) >= 0)
237 {
238 ++m_sent;
239 NS_LOG_INFO ("TraceDelay TX " << m_size << " bytes to "
240 << m_peerAddress << " Uid: " << p->GetUid ()
241 << " Time: " << (Simulator::Now ()).As (Time::S));
242
243 }
244 else
245 {
246 NS_LOG_INFO ("Error while sending " << m_size << " bytes to "
247 << m_peerAddress);
248 }
249
250 if (m_sent < m_count)
251 {
252 m_sendEvent = Simulator::Schedule (m_interval, &EpsBearerTagUdpClient::Send, this);
253 }
254 }
255
256
257
258 /**
259 * \ingroup lte-test
260 * \ingroup tests
261 *
262 * \brief Custom test structure to hold information of data transmitted in the uplink per UE
263 */
264 struct UeUlTestData
265 {
266 /**
267 * Constructor
268 *
269 * \param n number of packets
270 * \param s packet size
271 * \param r the RNTI
272 * \param l the BID
273 */
274 UeUlTestData (uint32_t n, uint32_t s, uint16_t r, uint8_t l);
275
276 uint32_t numPkts; ///< the number of packets sent
277 uint32_t pktSize; ///< the packet size
278 uint16_t rnti; ///< the RNTI
279 uint8_t bid; ///< the BID
280
281 Ptr<PacketSink> serverApp; ///< the server application
282 Ptr<Application> clientApp; ///< the client application
283 };
284
UeUlTestData(uint32_t n,uint32_t s,uint16_t r,uint8_t l)285 UeUlTestData::UeUlTestData (uint32_t n, uint32_t s, uint16_t r, uint8_t l)
286 : numPkts (n),
287 pktSize (s),
288 rnti (r),
289 bid (l)
290 {}
291
292 /**
293 * \ingroup lte-test
294 * \ingroup tests
295 *
296 * \brief Custom structure containing information about data sent in the uplink
297 * of eNodeB. Includes the information of the data sent in the uplink per UE.
298 */
299 struct EnbUlTestData
300 {
301 std::vector<UeUlTestData> ues; ///< the list of UEs
302 };
303
304
305 /**
306 * \ingroup lte-test
307 * \ingroup tests
308 *
309 * \brief EpcS1uUlTestCase class
310 */
311 class EpcS1uUlTestCase : public TestCase
312 {
313 public:
314 /**
315 * Constructor
316 *
317 * \param name the reference name
318 * \param v the list of UE lists
319 */
320 EpcS1uUlTestCase (std::string name, std::vector<EnbUlTestData> v);
321 virtual ~EpcS1uUlTestCase ();
322
323 private:
324 virtual void DoRun (void);
325 std::vector<EnbUlTestData> m_enbUlTestData; ///< ENB UL test data
326 };
327
328
EpcS1uUlTestCase(std::string name,std::vector<EnbUlTestData> v)329 EpcS1uUlTestCase::EpcS1uUlTestCase (std::string name, std::vector<EnbUlTestData> v)
330 : TestCase (name),
331 m_enbUlTestData (v)
332 {}
333
~EpcS1uUlTestCase()334 EpcS1uUlTestCase::~EpcS1uUlTestCase ()
335 {}
336
337 void
DoRun()338 EpcS1uUlTestCase::DoRun ()
339 {
340 Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
341 Ptr<Node> pgw = epcHelper->GetPgwNode ();
342
343 // allow jumbo packets
344 Config::SetDefault ("ns3::CsmaNetDevice::Mtu", UintegerValue (30000));
345 Config::SetDefault ("ns3::PointToPointNetDevice::Mtu", UintegerValue (30000));
346 epcHelper->SetAttribute ("S1uLinkMtu", UintegerValue (30000));
347
348 // Create a single RemoteHost
349 NodeContainer remoteHostContainer;
350 remoteHostContainer.Create (1);
351 Ptr<Node> remoteHost = remoteHostContainer.Get (0);
352 InternetStackHelper internet;
353 internet.Install (remoteHostContainer);
354
355 // Create the internet
356 PointToPointHelper p2ph;
357 p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
358 NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
359 Ipv4AddressHelper ipv4h;
360 ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
361 Ipv4InterfaceContainer internetNodesIpIfaceContainer = ipv4h.Assign (internetDevices);
362
363 // setup default gateway for the remote hosts
364 Ipv4StaticRoutingHelper ipv4RoutingHelper;
365 Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
366
367 // hardcoded UE addresses for now
368 remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.255.255.0"), 1);
369
370
371
372 uint16_t udpSinkPort = 1234;
373
374 NodeContainer enbs;
375 uint16_t cellIdCounter = 0;
376 uint64_t imsiCounter = 0;
377
378 for (std::vector<EnbUlTestData>::iterator enbit = m_enbUlTestData.begin ();
379 enbit < m_enbUlTestData.end ();
380 ++enbit)
381 {
382 Ptr<Node> enb = CreateObject<Node> ();
383 enbs.Add (enb);
384
385 // we test EPC without LTE, hence we use:
386 // 1) a CSMA network to simulate the cell
387 // 2) a raw socket opened on the CSMA device to simulate the LTE socket
388
389 uint16_t cellId = ++cellIdCounter;
390
391 NodeContainer ues;
392 ues.Create (enbit->ues.size ());
393
394 NodeContainer cell;
395 cell.Add (ues);
396 cell.Add (enb);
397
398 CsmaHelper csmaCell;
399 NetDeviceContainer cellDevices = csmaCell.Install (cell);
400
401 // the eNB's CSMA NetDevice acting as an LTE NetDevice.
402 Ptr<NetDevice> enbDevice = cellDevices.Get (cellDevices.GetN () - 1);
403
404 // Note that the EpcEnbApplication won't care of the actual NetDevice type
405 epcHelper->AddEnb (enb, enbDevice, cellId);
406
407 // Plug test RRC entity
408 Ptr<EpcEnbApplication> enbApp = enb->GetApplication (0)->GetObject<EpcEnbApplication> ();
409 NS_ASSERT_MSG (enbApp != 0, "cannot retrieve EpcEnbApplication");
410 Ptr<EpcTestRrc> rrc = CreateObject<EpcTestRrc> ();
411 enb->AggregateObject (rrc);
412 rrc->SetS1SapProvider (enbApp->GetS1SapProvider ());
413 enbApp->SetS1SapUser (rrc->GetS1SapUser ());
414
415 // we install the IP stack on UEs only
416 InternetStackHelper internet;
417 internet.Install (ues);
418
419 // assign IP address to UEs, and install applications
420 for (uint32_t u = 0; u < ues.GetN (); ++u)
421 {
422 Ptr<NetDevice> ueLteDevice = cellDevices.Get (u);
423 Ipv4InterfaceContainer ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevice));
424
425 Ptr<Node> ue = ues.Get (u);
426
427 // disable IP Forwarding on the UE. This is because we use
428 // CSMA broadcast MAC addresses for this test. The problem
429 // won't happen with a LteUeNetDevice.
430 Ptr<Ipv4> ueIpv4 = ue->GetObject<Ipv4> ();
431 ueIpv4->SetAttribute ("IpForward", BooleanValue (false));
432
433 // tell the UE to route all packets to the GW
434 Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueIpv4);
435 Ipv4Address gwAddr = epcHelper->GetUeDefaultGatewayAddress ();
436 NS_LOG_INFO ("GW address: " << gwAddr);
437 ueStaticRouting->SetDefaultRoute (gwAddr, 1);
438
439 // since the UEs in this test use CSMA with IP enabled, and
440 // the eNB uses CSMA but without IP, we fool the UE's ARP
441 // cache into thinking that the IP address of the GW can be
442 // reached by sending a CSMA packet to the broadcast
443 // address, so the eNB will get it.
444 int32_t ueLteIpv4IfIndex = ueIpv4->GetInterfaceForDevice (ueLteDevice);
445 Ptr<Ipv4L3Protocol> ueIpv4L3Protocol = ue->GetObject<Ipv4L3Protocol> ();
446 Ptr<Ipv4Interface> ueLteIpv4Iface = ueIpv4L3Protocol->GetInterface (ueLteIpv4IfIndex);
447 Ptr<ArpCache> ueArpCache = ueLteIpv4Iface->GetArpCache ();
448 ueArpCache->SetAliveTimeout (Seconds (1000));
449 ArpCache::Entry* arpCacheEntry = ueArpCache->Add (gwAddr);
450 arpCacheEntry->SetMacAddress (Mac48Address::GetBroadcast ());
451 arpCacheEntry->MarkPermanent ();
452
453
454 PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory",
455 InetSocketAddress (Ipv4Address::GetAny (), udpSinkPort));
456 ApplicationContainer sinkApp = packetSinkHelper.Install (remoteHost);
457 sinkApp.Start (Seconds (1.0));
458 sinkApp.Stop (Seconds (10.0));
459 enbit->ues[u].serverApp = sinkApp.Get (0)->GetObject<PacketSink> ();
460
461 Time interPacketInterval = Seconds (0.01);
462 Ptr<EpsBearerTagUdpClient> client = CreateObject<EpsBearerTagUdpClient> (enbit->ues[u].rnti, enbit->ues[u].bid);
463 client->SetAttribute ("RemoteAddress", Ipv4AddressValue (internetNodesIpIfaceContainer.GetAddress (1)));
464 client->SetAttribute ("RemotePort", UintegerValue (udpSinkPort));
465 client->SetAttribute ("MaxPackets", UintegerValue (enbit->ues[u].numPkts));
466 client->SetAttribute ("Interval", TimeValue (interPacketInterval));
467 client->SetAttribute ("PacketSize", UintegerValue (enbit->ues[u].pktSize));
468 ue->AddApplication (client);
469 ApplicationContainer clientApp;
470 clientApp.Add (client);
471 clientApp.Start (Seconds (2.0));
472 clientApp.Stop (Seconds (10.0));
473 enbit->ues[u].clientApp = client;
474
475 uint64_t imsi = ++imsiCounter;
476 epcHelper->AddUe (ueLteDevice, imsi);
477 epcHelper->ActivateEpsBearer (ueLteDevice, imsi, EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
478 Simulator::Schedule (MilliSeconds (10),
479 &EpcEnbS1SapProvider::InitialUeMessage,
480 enbApp->GetS1SapProvider (), imsi, enbit->ues[u].rnti);
481 // need this since all sinks are installed in the same node
482 ++udpSinkPort;
483 }
484
485 }
486
487 Simulator::Run ();
488
489 for (std::vector<EnbUlTestData>::iterator enbit = m_enbUlTestData.begin ();
490 enbit < m_enbUlTestData.end ();
491 ++enbit)
492 {
493 for (std::vector<UeUlTestData>::iterator ueit = enbit->ues.begin ();
494 ueit < enbit->ues.end ();
495 ++ueit)
496 {
497 NS_TEST_ASSERT_MSG_EQ (ueit->serverApp->GetTotalRx (), (ueit->numPkts) * (ueit->pktSize), "wrong total received bytes");
498 }
499 }
500
501 Simulator::Destroy ();
502 }
503
504
505
506
507
508 /**
509 * Test that the S1-U interface implementation works correctly
510 */
511 class EpcS1uUlTestSuite : public TestSuite
512 {
513 public:
514 EpcS1uUlTestSuite ();
515
516 } g_epcS1uUlTestSuiteInstance;
517
EpcS1uUlTestSuite()518 EpcS1uUlTestSuite::EpcS1uUlTestSuite ()
519 : TestSuite ("epc-s1u-uplink", SYSTEM)
520 {
521 std::vector<EnbUlTestData> v1;
522 EnbUlTestData e1;
523 UeUlTestData f1 (1, 100, 1, 1);
524 e1.ues.push_back (f1);
525 v1.push_back (e1);
526 AddTestCase (new EpcS1uUlTestCase ("1 eNB, 1UE", v1), TestCase::QUICK);
527
528
529 std::vector<EnbUlTestData> v2;
530 EnbUlTestData e2;
531 UeUlTestData f2_1 (1, 100, 1, 1);
532 e2.ues.push_back (f2_1);
533 UeUlTestData f2_2 (2, 200, 2, 1);
534 e2.ues.push_back (f2_2);
535 v2.push_back (e2);
536 AddTestCase (new EpcS1uUlTestCase ("1 eNB, 2UEs", v2), TestCase::QUICK);
537
538
539 std::vector<EnbUlTestData> v3;
540 v3.push_back (e1);
541 v3.push_back (e2);
542 AddTestCase (new EpcS1uUlTestCase ("2 eNBs", v3), TestCase::QUICK);
543
544
545 EnbUlTestData e3;
546 UeUlTestData f3_1 (3, 50, 1, 1);
547 e3.ues.push_back (f3_1);
548 UeUlTestData f3_2 (5, 1472, 2, 1);
549 e3.ues.push_back (f3_2);
550 UeUlTestData f3_3 (1, 1, 3, 1);
551 e3.ues.push_back (f3_2);
552 std::vector<EnbUlTestData> v4;
553 v4.push_back (e3);
554 v4.push_back (e1);
555 v4.push_back (e2);
556 AddTestCase (new EpcS1uUlTestCase ("3 eNBs", v4), TestCase::QUICK);
557
558 std::vector<EnbUlTestData> v5;
559 EnbUlTestData e5;
560 UeUlTestData f5 (10, 3000, 1, 1);
561 e5.ues.push_back (f5);
562 v5.push_back (e5);
563 AddTestCase (new EpcS1uUlTestCase ("1 eNB, 10 pkts 3000 bytes each", v5), TestCase::QUICK);
564
565 std::vector<EnbUlTestData> v6;
566 EnbUlTestData e6;
567 UeUlTestData f6 (50, 3000, 1, 1);
568 e6.ues.push_back (f6);
569 v6.push_back (e6);
570 AddTestCase (new EpcS1uUlTestCase ("1 eNB, 50 pkts 3000 bytes each", v6), TestCase::QUICK);
571
572 std::vector<EnbUlTestData> v7;
573 EnbUlTestData e7;
574 UeUlTestData f7 (10, 15000, 1, 1);
575 e7.ues.push_back (f7);
576 v7.push_back (e7);
577 AddTestCase (new EpcS1uUlTestCase ("1 eNB, 10 pkts 15000 bytes each", v7), TestCase::QUICK);
578
579 std::vector<EnbUlTestData> v8;
580 EnbUlTestData e8;
581 UeUlTestData f8 (100, 15000, 1, 1);
582 e8.ues.push_back (f8);
583 v8.push_back (e8);
584 AddTestCase (new EpcS1uUlTestCase ("1 eNB, 100 pkts 15000 bytes each", v8), TestCase::QUICK);
585
586 }
587