added EmuEpcHelper

This commit is contained in:
Nicola Baldo
2013-11-14 17:41:18 +01:00
parent 513740a776
commit fb295e22c9
5 changed files with 686 additions and 2 deletions

View File

@@ -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 <jaume.nin@cttc.cat>
*/
#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 <ns3/config-store-module.h>
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> lteHelper = CreateObject<LteHelper> ();
Ptr<EmuEpcHelper> epcHelper = CreateObject<EmuEpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
epcHelper->Initialize ();
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> 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<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
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<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
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<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
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;
}

View File

@@ -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'

View File

@@ -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 <jnin@cttc.es>
* Nicola Baldo <nbaldo@cttc.es>
* Manuel Requena <manuel.requena@cttc.es>
*/
#include <ns3/emu-epc-helper.h>
#include <ns3/log.h>
#include <ns3/inet-socket-address.h>
#include <ns3/mac48-address.h>
#include <ns3/eps-bearer.h>
#include <ns3/ipv4-address.h>
#include <ns3/internet-stack-helper.h>
#include <ns3/packet-socket-helper.h>
#include <ns3/packet-socket-address.h>
#include <ns3/epc-enb-application.h>
#include <ns3/epc-sgw-pgw-application.h>
#include <ns3/emu-fd-net-device-helper.h>
#include <ns3/lte-enb-rrc.h>
#include <ns3/epc-x2.h>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-ue-net-device.h>
#include <ns3/epc-mme.h>
#include <ns3/epc-ue-nas.h>
#include <ns3/string.h>
#include <ns3/abort.h>
#include <iomanip>
#include <iostream>
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<EpcHelper> ()
.AddConstructor<EmuEpcHelper> ()
.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<Node> ();
InternetStackHelper internet;
internet.SetIpv4StackInstall (true);
internet.Install (m_sgwPgw);
// create S1-U socket
Ptr<Socket> 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<VirtualNetDevice> ();
// 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<EpcSgwPgwApplication> (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<EpcMme> ();
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<NetDevice> 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<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> ());
m_tunDevice = 0;
m_sgwPgwApp = 0;
m_sgwPgw->Dispose ();
}
void
EmuEpcHelper::AddEnb (Ptr<Node> enb, Ptr<NetDevice> 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<Ipv4> ()->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<NetDevice> 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<Ipv4> ()->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<Ipv4> ()->GetNInterfaces ());
Ipv4Address enbAddress = enbIpIfaces.GetAddress (0);
Ipv4Address sgwAddress = m_sgwIpIfaces.GetAddress (0);
// create S1-U socket for the ENB
Ptr<Socket> 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<Socket> 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<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, enbAddress, sgwAddress, cellId);
enb->AddApplication (enbApp);
NS_ASSERT (enb->GetNApplications () == 1);
NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
NS_LOG_LOGIC ("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication (0));
NS_LOG_INFO ("Create EpcX2 entity");
Ptr<EpcX2> x2 = CreateObject<EpcX2> ();
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<Node> enb1, Ptr<Node> 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<Ipv4> enb1Ipv4 = enb1->GetObject<Ipv4> ();
Ptr<Ipv4> enb2Ipv4 = enb2->GetObject<Ipv4> ();
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<NetDevice> enb1EpcDev = enb1->GetDevice (2);
Ptr<NetDevice> 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<EpcX2> enb1X2 = enb1->GetObject<EpcX2> ();
Ptr<LteEnbNetDevice> enb1LteDev = enb1->GetDevice (0)->GetObject<LteEnbNetDevice> ();
uint16_t enb1CellId = enb1LteDev->GetCellId ();
NS_LOG_LOGIC ("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId);
Ptr<EpcX2> enb2X2 = enb2->GetObject<EpcX2> ();
Ptr<LteEnbNetDevice> enb2LteDev = enb2->GetDevice (0)->GetObject<LteEnbNetDevice> ();
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<NetDevice> ueDevice, uint64_t imsi)
{
NS_LOG_FUNCTION (this << imsi << ueDevice );
m_mme->AddUe (imsi);
m_sgwPgwApp->AddUe (imsi);
}
void
EmuEpcHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, uint64_t imsi, Ptr<EpcTft> 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<Node> ueNode = ueDevice->GetNode ();
Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4> ();
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<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
if (ueLteDevice)
{
Simulator::ScheduleNow (&EpcUeNas::ActivateEpsBearer, ueLteDevice->GetNas (), bearer, tft);
}
}
Ptr<Node>
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<Ipv4> ()->GetAddress (1, 0).GetLocal ();
}
} // namespace ns3

View File

@@ -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 <jnin@cttc.es>
* Nicola Baldo <nbaldo@cttc.es>
* Manuel Requena <manuel.requena@cttc.es>
*/
#ifndef EMU_EPC_HELPER_H
#define EMU_EPC_HELPER_H
#include <ns3/object.h>
#include <ns3/ipv4-address-helper.h>
#include <ns3/data-rate.h>
#include <ns3/epc-tft.h>
#include <ns3/eps-bearer.h>
#include <ns3/epc-helper.h>
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<Node> enbNode, Ptr<NetDevice> lteEnbNetDevice, uint16_t cellId);
virtual void AddUe (Ptr<NetDevice> ueLteDevice, uint64_t imsi);
virtual void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2);
virtual void ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer);
virtual Ptr<Node> 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<Node> m_sgwPgw;
Ptr<EpcSgwPgwApplication> m_sgwPgwApp;
Ptr<VirtualNetDevice> m_tunDevice;
Ptr<EpcMme> 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<uint64_t, Ptr<NetDevice> > 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

View File

@@ -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',