merge
This commit is contained in:
@@ -34,4 +34,7 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('lena-simple-epc',
|
||||
['lte'])
|
||||
obj.source = 'lena-simple-epc.cc'
|
||||
obj = bld.create_ns3_program('lena-x2-handover',
|
||||
['lte'])
|
||||
obj.source = 'lena-x2-handover.cc'
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
#include <ns3/epc-enb-application.h>
|
||||
#include <ns3/epc-sgw-pgw-application.h>
|
||||
|
||||
#include <ns3/lte-enb-rrc.h>
|
||||
#include <ns3/epc-x2.h>
|
||||
#include <ns3/lte-enb-net-device.h>
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -39,8 +43,10 @@ NS_LOG_COMPONENT_DEFINE ("EpcHelper");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (EpcHelper);
|
||||
|
||||
|
||||
EpcHelper::EpcHelper ()
|
||||
: m_gtpuUdpPort (2152) // fixed by the standard
|
||||
: m_gtpuUdpPort (2152), // fixed by the standard
|
||||
m_x2cUdpPort (4444) // fixed by the standard TODO
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
@@ -49,6 +55,8 @@ EpcHelper::EpcHelper ()
|
||||
// (remember that net broadcast and null address are not valid)
|
||||
m_s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.252");
|
||||
|
||||
m_x2Ipv4AddressHelper.SetBase ("12.0.0.0", "255.255.255.252");
|
||||
|
||||
// we use a /8 net for all UEs
|
||||
m_ueAddressHelper.SetBase ("7.0.0.0", "255.0.0.0");
|
||||
|
||||
@@ -191,7 +199,88 @@ EpcHelper::AddEnb (Ptr<Node> enb, Ptr<NetDevice> lteEnbNetDevice)
|
||||
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> ();
|
||||
NS_LOG_INFO ("Connect EpcX2 and LteEnbRrc entities");
|
||||
Ptr<LteEnbRrc> rrc = lteEnbNetDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
|
||||
x2->SetEpcX2SapUser (rrc->GetEpcX2SapUser ());
|
||||
rrc->SetEpcX2SapProvider (x2->GetEpcX2SapProvider ());
|
||||
|
||||
|
||||
enb->AggregateObject (x2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EpcHelper::AddX2Interface (Ptr<Node> enb1, Ptr<Node> enb2)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << enb1 << enb2);
|
||||
|
||||
// Create a point to point link between the two eNBs with
|
||||
// the corresponding new NetDevices on each side
|
||||
NodeContainer enbNodes;
|
||||
enbNodes.Add (enb1);
|
||||
enbNodes.Add (enb2);
|
||||
PointToPointHelper p2ph;
|
||||
// TODO Add m_x2Link*** parameters in epc.helper.h
|
||||
// TODO Create Make***Accessor functions
|
||||
// p2ph.SetDeviceAttribute ("DataRate", DataRateValue (m_x2LinkDataRate));
|
||||
// p2ph.SetDeviceAttribute ("Mtu", UintegerValue (m_x2LinkMtu));
|
||||
// p2ph.SetChannelAttribute ("Delay", TimeValue (m_x2LinkDelay));
|
||||
NetDeviceContainer enbDevices = p2ph.Install (enb1, enb2);
|
||||
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
|
||||
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
|
||||
Ptr<NetDevice> enb1Dev = enbDevices.Get (0);
|
||||
Ptr<NetDevice> enb2Dev = enbDevices.Get (1);
|
||||
|
||||
m_x2Ipv4AddressHelper.NewNetwork ();
|
||||
Ipv4InterfaceContainer enbIpIfaces = m_x2Ipv4AddressHelper.Assign (enbDevices);
|
||||
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after assigning Ipv4 addr to X2 dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
|
||||
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after assigning Ipv4 addr to X2 dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
|
||||
|
||||
Ipv4Address enb1Address = enbIpIfaces.GetAddress (0);
|
||||
Ipv4Address enb2Address = enbIpIfaces.GetAddress (1);
|
||||
|
||||
// Create X2-C socket for the eNB1
|
||||
Ptr<Socket> enb1X2cSocket = Socket::CreateSocket (enb1, TypeId::LookupByName ("ns3::UdpSocketFactory"));
|
||||
int retval = enb1X2cSocket->Bind (InetSocketAddress (enb1Address, m_x2cUdpPort));
|
||||
NS_ASSERT (retval == 0);
|
||||
|
||||
// Create X2-C socket for the eNB2
|
||||
Ptr<Socket> enb2X2cSocket = Socket::CreateSocket (enb2, TypeId::LookupByName ("ns3::UdpSocketFactory"));
|
||||
retval = enb2X2cSocket->Bind (InetSocketAddress (enb2Address, m_x2cUdpPort));
|
||||
NS_ASSERT (retval == 0);
|
||||
|
||||
|
||||
// Add X2 interface to the eNB1's X2 entity
|
||||
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);
|
||||
|
||||
// Add X2 interface to the eNB2's X2 entity
|
||||
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, enb1X2cSocket, enb2CellId, enb2X2cSocket);
|
||||
enb2X2->AddX2Interface (enb2CellId, enb2X2cSocket, enb1CellId, enb1X2cSocket);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EpcHelper::SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
|
||||
|
||||
Ptr<LteEnbRrc> sourceRrc = sourceEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
|
||||
|
||||
sourceRrc->SendHandoverRequest (ueNode, sourceEnbNode, targetEnbNode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ class Node;
|
||||
class NetDevice;
|
||||
class VirtualNetDevice;
|
||||
class EpcSgwPgwApplication;
|
||||
class EpcX2;
|
||||
|
||||
/**
|
||||
* \brief Helper class to handle the creation of the EPC entities and protocols.
|
||||
@@ -72,6 +73,17 @@ public:
|
||||
void AddEnb (Ptr<Node> enbNode, Ptr<NetDevice> lteEnbNetDevice);
|
||||
|
||||
|
||||
/**
|
||||
* Add an X2 interface between two eNB
|
||||
*
|
||||
* \param enbNode1 one eNB peer of the X2 interface
|
||||
* \param enbNode2 the other eNB peer of the X2 interface
|
||||
*/
|
||||
void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2);
|
||||
|
||||
void SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
|
||||
|
||||
|
||||
/**
|
||||
* Activate an EPS bearer, setting up the corresponding S1-U tunnel.
|
||||
*
|
||||
@@ -115,12 +127,10 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* helper to assign addresses to S1-U
|
||||
* NetDevices
|
||||
|
||||
/**
|
||||
* SGW-PGW network element
|
||||
*/
|
||||
Ipv4AddressHelper m_s1uIpv4AddressHelper;
|
||||
|
||||
/**
|
||||
* helper to assign addresses to UE devices as well as to the TUN device of the SGW/PGW
|
||||
@@ -130,17 +140,41 @@ private:
|
||||
Ptr<Node> m_sgwPgw;
|
||||
Ptr<EpcSgwPgwApplication> m_sgwPgwApp;
|
||||
Ptr<VirtualNetDevice> m_tunDevice;
|
||||
|
||||
|
||||
/**
|
||||
* S1-U interfaces
|
||||
*/
|
||||
|
||||
/**
|
||||
* helper to assign addresses to S1-U NetDevices
|
||||
*/
|
||||
Ipv4AddressHelper m_s1uIpv4AddressHelper;
|
||||
|
||||
DataRate m_s1uLinkDataRate;
|
||||
Time m_s1uLinkDelay;
|
||||
uint16_t m_s1uLinkMtu;
|
||||
|
||||
|
||||
/**
|
||||
* UDP port where the GTP-U Socket is bound, fixed by the standard as 2152
|
||||
*/
|
||||
uint16_t m_gtpuUdpPort;
|
||||
|
||||
|
||||
/**
|
||||
* helper to assign addresses to X2 NetDevices
|
||||
*/
|
||||
Ipv4AddressHelper m_x2Ipv4AddressHelper;
|
||||
|
||||
DataRate m_x2LinkDataRate;
|
||||
Time m_x2LinkDelay;
|
||||
uint16_t m_x2LinkMtu;
|
||||
|
||||
/**
|
||||
* UDP port where the GTP-U Socket is bound, fixed by the standard as 2152 TODO Check value in the spec
|
||||
*/
|
||||
uint16_t m_x2cUdpPort;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -570,6 +570,54 @@ LteHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<Epc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LteHelper::AddX2Interface (NodeContainer enbNodes)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
for (NodeContainer::Iterator i = enbNodes.Begin (); i != enbNodes.End (); ++i)
|
||||
{
|
||||
for (NodeContainer::Iterator j = i + 1; j != enbNodes.End (); ++j)
|
||||
{
|
||||
AddX2Interface (*i, *j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LteHelper::AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_INFO ("setting up the X2 interface");
|
||||
|
||||
m_epcHelper->AddX2Interface (enbNode1, enbNode2);
|
||||
}
|
||||
|
||||
void
|
||||
LteHelper::HandoverRequest (Time hoTime, Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
|
||||
Simulator::Schedule (hoTime, &LteHelper::DoHandoverRequest, this, ueNode, sourceEnbNode, targetEnbNode);
|
||||
}
|
||||
|
||||
void
|
||||
LteHelper::DoHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
|
||||
|
||||
m_epcHelper->SendHandoverRequest (ueNode, sourceEnbNode, targetEnbNode);
|
||||
|
||||
// lteHelper->Attach (ueNode, targetEnbNode);
|
||||
// lteHelper->ActivateEpsBearer (ueNode, *);
|
||||
|
||||
// lteHelper->DeactivateEpsBearer (ueNode, *);
|
||||
// lteHelper->Deattach (ueNode, sourceEnbNode);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeId
|
||||
LteHelper::GetRlcType (EpsBearer bearer)
|
||||
{
|
||||
|
||||
@@ -219,6 +219,33 @@ public:
|
||||
*/
|
||||
void ActivateEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft);
|
||||
|
||||
|
||||
/**
|
||||
* Create an X2 interface between all the eNBs in a given set
|
||||
*
|
||||
* \param enbNodes the set of eNB nodes
|
||||
*/
|
||||
void AddX2Interface (NodeContainer enbNodes);
|
||||
|
||||
/**
|
||||
* Create an X2 interface between two eNBs
|
||||
*
|
||||
* \param enbNode1 one eNB of the X2 interface
|
||||
* \param enbNode2 the other eNB of the X2 interface
|
||||
*/
|
||||
void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2);
|
||||
|
||||
/**
|
||||
* Trigger an X2-based handover of a UE between two eNBs
|
||||
*
|
||||
* \param hoTime when the Handover is initiated
|
||||
* \param ueNode the UE that hands off
|
||||
* \param enbNode1 source eNB, originally the UE is attached to this eNB
|
||||
* \param enbNode2 target eNB, the UE is finally connected to this eNB
|
||||
*/
|
||||
void HandoverRequest (Time hoTime, Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* \param bearer the specification of an EPS bearer
|
||||
@@ -320,6 +347,8 @@ private:
|
||||
Ptr<NetDevice> InstallSingleEnbDevice (Ptr<Node> n);
|
||||
Ptr<NetDevice> InstallSingleUeDevice (Ptr<Node> n);
|
||||
|
||||
void DoHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
|
||||
|
||||
Ptr<SpectrumChannel> m_downlinkChannel;
|
||||
Ptr<SpectrumChannel> m_uplinkChannel;
|
||||
|
||||
|
||||
@@ -41,19 +41,18 @@ public:
|
||||
|
||||
struct HandoverRequestParams
|
||||
{
|
||||
Ptr<Node> ueNode;
|
||||
Ptr<Node> sourceEnbNode;
|
||||
Ptr<Node> targetEnbNode;
|
||||
|
||||
uint32_t targetCellId;
|
||||
uint16_t cause;
|
||||
uint16_t sourceCellId;
|
||||
uint16_t targetCellId;
|
||||
std::list<uint32_t> bearers;
|
||||
Ptr<Packet> rrcContext;
|
||||
};
|
||||
|
||||
struct HandoverRequestAckParams
|
||||
{
|
||||
Ptr<Node> ueNode;
|
||||
|
||||
uint16_t cause;
|
||||
uint16_t sourceCellId;
|
||||
uint16_t targetCellId;
|
||||
std::list<uint32_t> bearers;
|
||||
Ptr<Packet> rrcContext;
|
||||
};
|
||||
@@ -84,13 +83,18 @@ public:
|
||||
|
||||
struct HandoverRequestParams
|
||||
{
|
||||
uint32_t targetCellId;
|
||||
uint16_t cause;
|
||||
uint16_t sourceCellId;
|
||||
uint16_t targetCellId;
|
||||
std::list<uint32_t> bearers;
|
||||
Ptr<Packet> rrcContext;
|
||||
};
|
||||
|
||||
struct HandoverRequestAckParams
|
||||
{
|
||||
uint16_t cause;
|
||||
uint16_t sourceCellId;
|
||||
uint16_t targetCellId;
|
||||
std::list<uint32_t> bearers;
|
||||
Ptr<Packet> rrcContext;
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "ns3/object-factory.h"
|
||||
|
||||
#include "ns3/lte-enb-rrc.h"
|
||||
#include "ns3/lte-enb-net-device.h"
|
||||
#include "ns3/lte-rlc.h"
|
||||
#include "ns3/lte-pdcp.h"
|
||||
#include "ns3/lte-pdcp-sap.h"
|
||||
@@ -47,9 +48,6 @@ NS_LOG_COMPONENT_DEFINE ("LteEnbRrc");
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ///////////////////////////
|
||||
// CMAC SAP forwarder
|
||||
// ///////////////////////////
|
||||
@@ -459,30 +457,37 @@ void
|
||||
LteEnbRrc::SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
|
||||
NS_LOG_INFO ("Request to send HANDOVER REQUEST");
|
||||
NS_LOG_LOGIC ("Request to send HANDOVER REQUEST");
|
||||
|
||||
EpcX2SapProvider::HandoverRequestParams params;
|
||||
params.ueNode = ueNode;
|
||||
params.sourceEnbNode = sourceEnbNode;
|
||||
params.targetEnbNode = targetEnbNode;
|
||||
params.sourceCellId = sourceEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetCellId ();
|
||||
params.targetCellId = targetEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetCellId ();
|
||||
|
||||
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
|
||||
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
|
||||
|
||||
m_x2SapProvider->SendHandoverRequest (params);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// X2-User SAP
|
||||
// X2 User SAP
|
||||
//
|
||||
void
|
||||
LteEnbRrc::DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
NS_LOG_INFO ("Recv X2 message: HANDOVER REQUEST");
|
||||
NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST");
|
||||
|
||||
NS_LOG_INFO ("Send X2 message: HANDOVER REQUEST ACK");
|
||||
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
|
||||
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
|
||||
|
||||
NS_LOG_LOGIC ("Send X2 message: HANDOVER REQUEST ACK");
|
||||
|
||||
EpcX2SapProvider::HandoverRequestAckParams ackParams;
|
||||
ackParams.sourceCellId = params.sourceCellId;
|
||||
ackParams.targetCellId = params.targetCellId;
|
||||
|
||||
m_x2SapProvider->SendHandoverRequestAck (ackParams);
|
||||
}
|
||||
@@ -492,7 +497,10 @@ LteEnbRrc::DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams para
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
NS_LOG_INFO ("Recv X2 message: HANDOVER REQUEST ACK");
|
||||
NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST ACK");
|
||||
|
||||
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
|
||||
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "lte-enb-net-device.h"
|
||||
#include "ns3/lte-enb-net-device.h"
|
||||
#include "lte-ue-net-device.h"
|
||||
#include "lte-ue-mac.h"
|
||||
#include "lte-ue-rrc.h"
|
||||
|
||||
Reference in New Issue
Block a user