From fb295e22c9c8a679b2f9a345fdc86d9824918c1e Mon Sep 17 00:00:00 2001 From: Nicola Baldo Date: Thu, 14 Nov 2013 17:41:18 +0100 Subject: [PATCH] added EmuEpcHelper --- src/lte/examples/lena-simple-epc-emu.cc | 192 +++++++++++++ src/lte/examples/wscript | 4 +- src/lte/helper/emu-epc-helper.cc | 363 ++++++++++++++++++++++++ src/lte/helper/emu-epc-helper.h | 125 ++++++++ src/lte/wscript | 4 +- 5 files changed, 686 insertions(+), 2 deletions(-) create mode 100644 src/lte/examples/lena-simple-epc-emu.cc create mode 100644 src/lte/helper/emu-epc-helper.cc create mode 100644 src/lte/helper/emu-epc-helper.h diff --git a/src/lte/examples/lena-simple-epc-emu.cc b/src/lte/examples/lena-simple-epc-emu.cc new file mode 100644 index 000000000..214d1ccb4 --- /dev/null +++ b/src/lte/examples/lena-simple-epc-emu.cc @@ -0,0 +1,192 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 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: Jaume Nin + */ + +#include "ns3/lte-helper.h" +#include "ns3/epc-helper.h" +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/ipv4-global-routing-helper.h" +#include "ns3/internet-module.h" +#include "ns3/mobility-module.h" +#include "ns3/lte-module.h" +#include "ns3/applications-module.h" +#include "ns3/point-to-point-helper.h" +#include + +using namespace ns3; + +/** + * Sample simulation script for LTE+EPC. It instantiates several eNodeB, + * attaches one UE per eNodeB starts a flow for each UE to and from a remote host. + * It also starts yet another flow between each UE pair. + */ +NS_LOG_COMPONENT_DEFINE ("EpcFirstExample"); +int +main (int argc, char *argv[]) +{ + + uint16_t numberOfNodes = 1; + double simTime = 10.1; + double distance = 60.0; + double interPacketInterval = 1000; + + // Command line arguments + CommandLine cmd; + cmd.AddValue("numberOfNodes", "Number of eNodeBs + UE pairs", numberOfNodes); + cmd.AddValue("simTime", "Total duration of the simulation [s])", simTime); + cmd.AddValue("distance", "Distance between eNBs [m]", distance); + cmd.AddValue("interPacketInterval", "Inter packet interval [ms])", interPacketInterval); + cmd.Parse(argc, argv); + + // let's go in real time + // NOTE: if you go in real time I strongly advise to use + // --ns3::RealtimeSimulatorImpl::SynchronizationMode=HardLimit + // I've seen that if BestEffort is used things can break + // (even simple stuff such as ARP) + //GlobalValue::Bind ("SimulatorImplementationType", + // StringValue ("ns3::RealtimeSimulatorImpl")); + + // and let's try to speed things up + Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false)); + Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); + + GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true)); + + ConfigStore inputConfig; + inputConfig.ConfigureDefaults(); + + // parse again so you can override default values from the command line + cmd.Parse(argc, argv); + + + + Ptr lteHelper = CreateObject (); + Ptr epcHelper = CreateObject (); + lteHelper->SetEpcHelper (epcHelper); + epcHelper->Initialize (); + + Ptr pgw = epcHelper->GetPgwNode (); + + // Create a single RemoteHost + NodeContainer remoteHostContainer; + remoteHostContainer.Create (1); + Ptr 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); + // interface 0 is localhost, 1 is the p2p device + Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1); + + Ipv4StaticRoutingHelper ipv4RoutingHelper; + Ptr remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject ()); + remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1); + + NodeContainer ueNodes; + NodeContainer enbNodes; + enbNodes.Create(numberOfNodes); + ueNodes.Create(numberOfNodes); + + // Install Mobility Model + Ptr positionAlloc = CreateObject (); + for (uint16_t i = 0; i < numberOfNodes; i++) + { + positionAlloc->Add (Vector(distance * i, 0, 0)); + } + MobilityHelper mobility; + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + mobility.SetPositionAllocator(positionAlloc); + mobility.Install(enbNodes); + mobility.Install(ueNodes); + + // Install LTE Devices to the nodes + NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes); + NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ueNodes); + + // Install the IP stack on the UEs + internet.Install (ueNodes); + Ipv4InterfaceContainer ueIpIface; + ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevs)); + // Assign IP address to UEs, and install applications + for (uint32_t u = 0; u < ueNodes.GetN (); ++u) + { + Ptr ueNode = ueNodes.Get (u); + // Set the default gateway for the UE + Ptr ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject ()); + ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1); + } + + // Attach one UE per eNodeB + for (uint16_t i = 0; i < numberOfNodes; i++) + { + lteHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(i)); + // side effect: the default EPS bearer will be activated + } + + + // Install and start applications on UEs and remote host + uint16_t dlPort = 1234; + uint16_t ulPort = 2000; + ApplicationContainer clientApps; + ApplicationContainer serverApps; + for (uint32_t u = 0; u < ueNodes.GetN (); ++u) + { + ++ulPort; + PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort)); + PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort)); + serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get(u))); + serverApps.Add (ulPacketSinkHelper.Install (remoteHost)); + + UdpClientHelper dlClient (ueIpIface.GetAddress (u), dlPort); + dlClient.SetAttribute ("Interval", TimeValue (MilliSeconds(interPacketInterval))); + dlClient.SetAttribute ("MaxPackets", UintegerValue(1000000)); + + UdpClientHelper ulClient (remoteHostAddr, ulPort); + ulClient.SetAttribute ("Interval", TimeValue (MilliSeconds(interPacketInterval))); + ulClient.SetAttribute ("MaxPackets", UintegerValue(1000000)); + + clientApps.Add (dlClient.Install (remoteHost)); + clientApps.Add (ulClient.Install (ueNodes.Get(u))); + } + serverApps.Start (Seconds (0.01)); + clientApps.Start (Seconds (0.01)); + lteHelper->EnableTraces (); + // Uncomment to enable PCAP tracing + //p2ph.EnablePcapAll("lena-epc-first"); + + Simulator::Stop(Seconds(simTime)); + Simulator::Run(); + + /*GtkConfigStore config; + config.ConfigureAttributes();*/ + + Simulator::Destroy(); + return 0; + +} + diff --git a/src/lte/examples/wscript b/src/lte/examples/wscript index 43c03f849..99e7f0109 100644 --- a/src/lte/examples/wscript +++ b/src/lte/examples/wscript @@ -40,4 +40,6 @@ def build(bld): obj = bld.create_ns3_program('lena-x2-handover-measures', ['lte']) obj.source = 'lena-x2-handover-measures.cc' - + obj = bld.create_ns3_program('lena-simple-epc-emu', + ['lte']) + obj.source = 'lena-simple-epc-emu.cc' diff --git a/src/lte/helper/emu-epc-helper.cc b/src/lte/helper/emu-epc-helper.cc new file mode 100644 index 000000000..7768cf29c --- /dev/null +++ b/src/lte/helper/emu-epc-helper.cc @@ -0,0 +1,363 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011-2013 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: Jaume Nin + * Nicola Baldo + * Manuel Requena + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("EmuEpcHelper"); + +NS_OBJECT_ENSURE_REGISTERED (EmuEpcHelper); + + +EmuEpcHelper::EmuEpcHelper () + : m_gtpuUdpPort (2152) // fixed by the standard +{ + NS_LOG_FUNCTION (this); + +} + +EmuEpcHelper::~EmuEpcHelper () +{ + NS_LOG_FUNCTION (this); +} + +TypeId +EmuEpcHelper::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::EmuEpcHelper") + .SetParent () + .AddConstructor () + .AddAttribute ("sgwDeviceName", + "The name of the device used for the S1-U interface of the SGW", + StringValue ("veth0"), + MakeStringAccessor (&EmuEpcHelper::m_sgwDeviceName), + MakeStringChecker ()) + .AddAttribute ("enbDeviceName", + "The name of the device used for the S1-U interface of the eNB", + StringValue ("veth1"), + MakeStringAccessor (&EmuEpcHelper::m_enbDeviceName), + MakeStringChecker ()) + .AddAttribute ("SgwMacAddress", + "MAC address used for the SGW ", + StringValue ("00:00:00:59:00:aa"), + MakeStringAccessor (&EmuEpcHelper::m_sgwMacAddress), + MakeStringChecker ()) + .AddAttribute ("EnbMacAddressBase", + "First 5 bytes of the Enb MAC address base", + StringValue ("00:00:00:eb:00"), + MakeStringAccessor (&EmuEpcHelper::m_enbMacAddressBase), + MakeStringChecker ()) + ; + return tid; +} + +void +EmuEpcHelper::DoInitialize () +{ + NS_LOG_LOGIC (this); + + + // we use a /8 net for all UEs + m_ueAddressHelper.SetBase ("7.0.0.0", "255.0.0.0"); + + + + // create SgwPgwNode + m_sgwPgw = CreateObject (); + InternetStackHelper internet; + internet.SetIpv4StackInstall (true); + internet.Install (m_sgwPgw); + + // create S1-U socket + Ptr sgwPgwS1uSocket = Socket::CreateSocket (m_sgwPgw, TypeId::LookupByName ("ns3::UdpSocketFactory")); + int retval = sgwPgwS1uSocket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_gtpuUdpPort)); + NS_ASSERT (retval == 0); + + // create TUN device implementing tunneling of user data over GTP-U/UDP/IP + m_tunDevice = CreateObject (); + // allow jumbo packets + m_tunDevice->SetAttribute ("Mtu", UintegerValue (30000)); + + // yes we need this + m_tunDevice->SetAddress (Mac48Address::Allocate ()); + + m_sgwPgw->AddDevice (m_tunDevice); + NetDeviceContainer tunDeviceContainer; + tunDeviceContainer.Add (m_tunDevice); + + // the TUN device is on the same subnet as the UEs, so when a packet + // addressed to an UE arrives at the intenet to the WAN interface of + // the PGW it will be forwarded to the TUN device. + Ipv4InterfaceContainer tunDeviceIpv4IfContainer = m_ueAddressHelper.Assign (tunDeviceContainer); + + // create EpcSgwPgwApplication + m_sgwPgwApp = CreateObject (m_tunDevice, sgwPgwS1uSocket); + m_sgwPgw->AddApplication (m_sgwPgwApp); + + // connect SgwPgwApplication and virtual net device for tunneling + m_tunDevice->SetSendCallback (MakeCallback (&EpcSgwPgwApplication::RecvFromTunDevice, m_sgwPgwApp)); + + // Create MME and connect with SGW via S11 interface + m_mme = CreateObject (); + m_mme->SetS11SapSgw (m_sgwPgwApp->GetS11SapSgw ()); + m_sgwPgwApp->SetS11SapMme (m_mme->GetS11SapMme ()); + + // Create EmuFdNetDevice for SGW + EmuFdNetDeviceHelper emu; + NS_LOG_LOGIC ("SGW device: " << m_sgwDeviceName); + emu.SetDeviceName (m_sgwDeviceName); + NetDeviceContainer sgwDevices = emu.Install (m_sgwPgw); + Ptr sgwDevice = sgwDevices.Get (0); + NS_LOG_LOGIC ("MAC address of SGW: " << m_sgwMacAddress); + sgwDevice->SetAttribute ("Address", Mac48AddressValue (m_sgwMacAddress.c_str ())); + + // we use a /8 subnet so the SGW and the eNBs can talk directly to each other + m_epcIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.0", "0.0.0.1"); + m_sgwIpIfaces = m_epcIpv4AddressHelper.Assign (sgwDevices); + m_epcIpv4AddressHelper.SetBase ("10.0.0.0", "255.0.0.0", "0.1.1.1"); + + + EpcHelper::DoInitialize (); +} + +void +EmuEpcHelper::DoDispose () +{ + NS_LOG_FUNCTION (this); + m_tunDevice->SetSendCallback (MakeNullCallback, const Address&, const Address&, uint16_t> ()); + m_tunDevice = 0; + m_sgwPgwApp = 0; + m_sgwPgw->Dispose (); +} + + +void +EmuEpcHelper::AddEnb (Ptr enb, Ptr lteEnbNetDevice, uint16_t cellId) +{ + NS_LOG_FUNCTION (this << enb << lteEnbNetDevice << cellId); + + Initialize (); + + NS_ASSERT (enb == lteEnbNetDevice->GetNode ()); + + // add an IPv4 stack to the previously created eNB + InternetStackHelper internet; + internet.Install (enb); + NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after node creation: " << enb->GetObject ()->GetNInterfaces ()); + + + + // Create an EmuFdNetDevice for the eNB to connect with the SGW and other eNBs + EmuFdNetDeviceHelper emu; + NS_LOG_LOGIC ("eNB device: " << m_enbDeviceName); + emu.SetDeviceName (m_enbDeviceName); + NetDeviceContainer enbDevices = emu.Install (enb); + + NS_ABORT_IF ((cellId == 0) || (cellId > 255)); + std::ostringstream enbMacAddress; + enbMacAddress << m_enbMacAddressBase << ":" << std::hex << std::setfill ('0') << std::setw (2) << cellId; + NS_LOG_LOGIC ("MAC address of enB with cellId " << cellId << " : " << enbMacAddress.str ()); + Ptr enbDev = enbDevices.Get (0); + enbDev->SetAttribute ("Address", Mac48AddressValue (enbMacAddress.str ().c_str ())); + + //emu.EnablePcap ("enbDevice", enbDev); + + NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after installing emu dev: " << enb->GetObject ()->GetNInterfaces ()); + Ipv4InterfaceContainer enbIpIfaces = m_epcIpv4AddressHelper.Assign (enbDevices); + NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after assigning Ipv4 addr to S1 dev: " << enb->GetObject ()->GetNInterfaces ()); + + Ipv4Address enbAddress = enbIpIfaces.GetAddress (0); + Ipv4Address sgwAddress = m_sgwIpIfaces.GetAddress (0); + + // create S1-U socket for the ENB + Ptr enbS1uSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::UdpSocketFactory")); + int retval = enbS1uSocket->Bind (InetSocketAddress (enbAddress, m_gtpuUdpPort)); + NS_ASSERT (retval == 0); + + // create LTE socket for the ENB + Ptr enbLteSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::PacketSocketFactory")); + PacketSocketAddress enbLteSocketBindAddress; + enbLteSocketBindAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ()); + enbLteSocketBindAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER); + retval = enbLteSocket->Bind (enbLteSocketBindAddress); + NS_ASSERT (retval == 0); + PacketSocketAddress enbLteSocketConnectAddress; + enbLteSocketConnectAddress.SetPhysicalAddress (Mac48Address::GetBroadcast ()); + enbLteSocketConnectAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ()); + enbLteSocketConnectAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER); + retval = enbLteSocket->Connect (enbLteSocketConnectAddress); + NS_ASSERT (retval == 0); + + + NS_LOG_INFO ("create EpcEnbApplication"); + Ptr enbApp = CreateObject (enbLteSocket, enbS1uSocket, enbAddress, sgwAddress, cellId); + enb->AddApplication (enbApp); + NS_ASSERT (enb->GetNApplications () == 1); + NS_ASSERT_MSG (enb->GetApplication (0)->GetObject () != 0, "cannot retrieve EpcEnbApplication"); + NS_LOG_LOGIC ("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication (0)); + + + NS_LOG_INFO ("Create EpcX2 entity"); + Ptr x2 = CreateObject (); + enb->AggregateObject (x2); + + NS_LOG_INFO ("connect S1-AP interface"); + m_mme->AddEnb (cellId, enbAddress, enbApp->GetS1apSapEnb ()); + m_sgwPgwApp->AddEnb (cellId, enbAddress, sgwAddress); + enbApp->SetS1apSapMme (m_mme->GetS1apSapMme ()); +} + + +void +EmuEpcHelper::AddX2Interface (Ptr enb1, Ptr enb2) +{ + NS_LOG_FUNCTION (this << enb1 << enb2); + + NS_LOG_WARN ("X2 support still untested"); + + + // for X2, we reuse the same device and IP address of the S1-U interface + Ptr enb1Ipv4 = enb1->GetObject (); + Ptr enb2Ipv4 = enb2->GetObject (); + NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1: " << enb1Ipv4->GetNInterfaces ()); + NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2: " << enb2Ipv4->GetNInterfaces ()); + NS_LOG_LOGIC ("number of NetDevices of the eNB #1: " << enb1->GetNDevices ()); + NS_LOG_LOGIC ("number of NetDevices of the eNB #2: " << enb2->GetNDevices ()); + + // 0 is the LTE device, 1 is localhost, 2 is the EPC NetDevice + Ptr enb1EpcDev = enb1->GetDevice (2); + Ptr enb2EpcDev = enb2->GetDevice (2); + + int32_t enb1Interface = enb1Ipv4->GetInterfaceForDevice (enb1EpcDev); + int32_t enb2Interface = enb2Ipv4->GetInterfaceForDevice (enb2EpcDev); + NS_ASSERT (enb1Interface >= 0); + NS_ASSERT (enb2Interface >= 0); + NS_ASSERT (enb1Ipv4->GetNAddresses (enb1Interface) == 1); + NS_ASSERT (enb2Ipv4->GetNAddresses (enb2Interface) == 1); + Ipv4Address enb1Addr = enb1Ipv4->GetAddress (enb1Interface, 0).GetLocal (); + Ipv4Address enb2Addr = enb2Ipv4->GetAddress (enb2Interface, 0).GetLocal (); + NS_LOG_LOGIC (" eNB 1 IP address: " << enb1Addr); + NS_LOG_LOGIC (" eNB 2 IP address: " << enb2Addr); + + // Add X2 interface to both eNBs' X2 entities + Ptr enb1X2 = enb1->GetObject (); + Ptr enb1LteDev = enb1->GetDevice (0)->GetObject (); + uint16_t enb1CellId = enb1LteDev->GetCellId (); + NS_LOG_LOGIC ("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId); + + Ptr enb2X2 = enb2->GetObject (); + Ptr enb2LteDev = enb2->GetDevice (0)->GetObject (); + uint16_t enb2CellId = enb2LteDev->GetCellId (); + NS_LOG_LOGIC ("LteEnbNetDevice #2 = " << enb2LteDev << " - CellId = " << enb2CellId); + + enb1X2->AddX2Interface (enb1CellId, enb1Addr, enb2CellId, enb2Addr); + enb2X2->AddX2Interface (enb2CellId, enb2Addr, enb1CellId, enb1Addr); + + enb1LteDev->GetRrc ()->AddX2Neighbour (enb2LteDev->GetCellId ()); + enb2LteDev->GetRrc ()->AddX2Neighbour (enb1LteDev->GetCellId ()); +} + + +void +EmuEpcHelper::AddUe (Ptr ueDevice, uint64_t imsi) +{ + NS_LOG_FUNCTION (this << imsi << ueDevice ); + + m_mme->AddUe (imsi); + m_sgwPgwApp->AddUe (imsi); + +} + +void +EmuEpcHelper::ActivateEpsBearer (Ptr ueDevice, uint64_t imsi, Ptr tft, EpsBearer bearer) +{ + NS_LOG_FUNCTION (this << ueDevice << imsi); + + // we now retrieve the IPv4 address of the UE and notify it to the SGW; + // we couldn't do it before since address assignment is triggered by + // the user simulation program, rather than done by the EPC + Ptr ueNode = ueDevice->GetNode (); + Ptr ueIpv4 = ueNode->GetObject (); + NS_ASSERT_MSG (ueIpv4 != 0, "UEs need to have IPv4 installed before EPS bearers can be activated"); + int32_t interface = ueIpv4->GetInterfaceForDevice (ueDevice); + NS_ASSERT (interface >= 0); + NS_ASSERT (ueIpv4->GetNAddresses (interface) == 1); + Ipv4Address ueAddr = ueIpv4->GetAddress (interface, 0).GetLocal (); + NS_LOG_LOGIC (" UE IP address: " << ueAddr); m_sgwPgwApp->SetUeAddress (imsi, ueAddr); + + m_mme->AddBearer (imsi, tft, bearer); + Ptr ueLteDevice = ueDevice->GetObject (); + if (ueLteDevice) + { + Simulator::ScheduleNow (&EpcUeNas::ActivateEpsBearer, ueLteDevice->GetNas (), bearer, tft); + } +} + + +Ptr +EmuEpcHelper::GetPgwNode () +{ + return m_sgwPgw; +} + + +Ipv4InterfaceContainer +EmuEpcHelper::AssignUeIpv4Address (NetDeviceContainer ueDevices) +{ + return m_ueAddressHelper.Assign (ueDevices); +} + + + +Ipv4Address +EmuEpcHelper::GetUeDefaultGatewayAddress () +{ + // return the address of the tun device + return m_sgwPgw->GetObject ()->GetAddress (1, 0).GetLocal (); +} + + +} // namespace ns3 diff --git a/src/lte/helper/emu-epc-helper.h b/src/lte/helper/emu-epc-helper.h new file mode 100644 index 000000000..a35053392 --- /dev/null +++ b/src/lte/helper/emu-epc-helper.h @@ -0,0 +1,125 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011-2013 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: Jaume Nin + * Nicola Baldo + * Manuel Requena + */ + +#ifndef EMU_EPC_HELPER_H +#define EMU_EPC_HELPER_H + +#include +#include +#include +#include +#include +#include + +namespace ns3 { + +class Node; +class NetDevice; +class VirtualNetDevice; +class EpcSgwPgwApplication; +class EpcX2; +class EpcMme; + +/** + * \brief Create an EPC network using EmuFdNetDevice + * + * This Helper will create an EPC network topology comprising of a + * single node that implements both the SGW and PGW functionality, and + * an MME node. The S1-U, X2-U and X2-C interfaces are realized using + * EmuFdNetDevice; in particular, one device is used to send all + */ +class EmuEpcHelper : public EpcHelper +{ +public: + + /** + * Constructor + */ + EmuEpcHelper (); + + /** + * Destructor + */ + virtual ~EmuEpcHelper (); + + // inherited from Object + static TypeId GetTypeId (void); + virtual void DoInitialize (); + virtual void DoDispose (); + + // inherited from EpcHelper + virtual void AddEnb (Ptr enbNode, Ptr lteEnbNetDevice, uint16_t cellId); + virtual void AddUe (Ptr ueLteDevice, uint64_t imsi); + virtual void AddX2Interface (Ptr enbNode1, Ptr enbNode2); + virtual void ActivateEpsBearer (Ptr ueLteDevice, uint64_t imsi, Ptr tft, EpsBearer bearer); + virtual Ptr GetPgwNode (); + virtual Ipv4InterfaceContainer AssignUeIpv4Address (NetDeviceContainer ueDevices); + virtual Ipv4Address GetUeDefaultGatewayAddress (); + + + +private: + + /** + * helper to assign addresses to UE devices as well as to the TUN device of the SGW/PGW + */ + Ipv4AddressHelper m_ueAddressHelper; + + + /** + * SGW-PGW network element + */ + Ptr m_sgwPgw; + Ptr m_sgwPgwApp; + Ptr m_tunDevice; + Ptr m_mme; + + /** + * helper to assign addresses to S1-U NetDevices + */ + Ipv4AddressHelper m_epcIpv4AddressHelper; + + /** + * UDP port where the GTP-U Socket is bound, fixed by the standard as 2152 + */ + uint16_t m_gtpuUdpPort; + + /** + * Map storing for each IMSI the corresponding eNB NetDevice + * + */ + std::map > m_imsiEnbDeviceMap; + + Ipv4InterfaceContainer m_sgwIpIfaces; + + std::string m_sgwDeviceName; + std::string m_enbDeviceName; + std::string m_sgwMacAddress; + std::string m_enbMacAddressBase; +}; + + + + +} // namespace ns3 + +#endif // EMU_EPC_HELPER_H diff --git a/src/lte/wscript b/src/lte/wscript index 239348cc2..28a8882e6 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -2,7 +2,7 @@ def build(bld): - module = bld.create_ns3_module('lte', ['core', 'network', 'spectrum', 'stats', 'buildings', 'virtual-net-device','point-to-point','applications','internet','csma']) + module = bld.create_ns3_module('lte', ['core', 'network', 'spectrum', 'stats', 'buildings', 'virtual-net-device','point-to-point','applications','internet','csma','fd-net-device']) module.source = [ 'model/lte-common.cc', 'model/lte-spectrum-phy.cc', @@ -41,6 +41,7 @@ def build(bld): 'helper/lte-stats-calculator.cc', 'helper/epc-helper.cc', 'helper/point-to-point-epc-helper.cc', + 'helper/emu-epc-helper.cc', 'helper/radio-bearer-stats-calculator.cc', 'helper/radio-bearer-stats-connector.cc', 'helper/phy-stats-calculator.cc', @@ -195,6 +196,7 @@ def build(bld): 'helper/lte-stats-calculator.h', 'helper/epc-helper.h', 'helper/point-to-point-epc-helper.h', + 'helper/emu-epc-helper.h', 'helper/phy-stats-calculator.h', 'helper/mac-stats-calculator.h', 'helper/phy-tx-stats-calculator.h',