--- a/src/lte/model/epc-x2-header.cc Mon Dec 03 17:48:23 2012 +0100
+++ b/src/lte/model/epc-x2-header.cc Mon Dec 03 17:49:23 2012 +0100
@@ -658,6 +658,131 @@
/////////////////////////////////////////////////////////////////////
+NS_OBJECT_ENSURE_REGISTERED (EpcX2HandoverPreparationFailureHeader);
+
+EpcX2HandoverPreparationFailureHeader::EpcX2HandoverPreparationFailureHeader ()
+ : m_numberOfIes (1 + 1 + 1),
+ m_headerLength (2 + 2 + 2),
+ m_oldEnbUeX2apId (0xfffa),
+ m_cause (0xfffa),
+ m_criticalityDiagnostics (0xfffa)
+{
+}
+
+EpcX2HandoverPreparationFailureHeader::~EpcX2HandoverPreparationFailureHeader ()
+{
+ m_numberOfIes = 0;
+ m_headerLength = 0;
+ m_oldEnbUeX2apId = 0xfffb;
+ m_cause = 0xfffb;
+ m_criticalityDiagnostics = 0xfffb;
+}
+
+TypeId
+EpcX2HandoverPreparationFailureHeader::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::EpcX2HandoverPreparationFailureHeader")
+ .SetParent<Header> ()
+ .AddConstructor<EpcX2HandoverPreparationFailureHeader> ()
+ ;
+ return tid;
+}
+
+TypeId
+EpcX2HandoverPreparationFailureHeader::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+
+uint32_t
+EpcX2HandoverPreparationFailureHeader::GetSerializedSize (void) const
+{
+ return m_headerLength;
+}
+
+void
+EpcX2HandoverPreparationFailureHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteHtonU16 (m_oldEnbUeX2apId);
+ i.WriteHtonU16 (m_cause);
+ i.WriteHtonU16 (m_criticalityDiagnostics);
+}
+
+uint32_t
+EpcX2HandoverPreparationFailureHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ m_oldEnbUeX2apId = i.ReadNtohU16 ();
+ m_cause = i.ReadNtohU16 ();
+ m_criticalityDiagnostics = i.ReadNtohU16 ();
+
+ m_headerLength = 6;
+ m_numberOfIes = 3;
+
+ return GetSerializedSize ();
+}
+
+void
+EpcX2HandoverPreparationFailureHeader::Print (std::ostream &os) const
+{
+ os << "OldEnbUeX2apId = " << m_oldEnbUeX2apId;
+ os << " Cause = " << m_cause;
+ os << " CriticalityDiagnostics = " << m_criticalityDiagnostics;
+}
+
+uint16_t
+EpcX2HandoverPreparationFailureHeader::GetOldEnbUeX2apId () const
+{
+ return m_oldEnbUeX2apId;
+}
+
+void
+EpcX2HandoverPreparationFailureHeader::SetOldEnbUeX2apId (uint16_t x2apId)
+{
+ m_oldEnbUeX2apId = x2apId;
+}
+
+uint16_t
+EpcX2HandoverPreparationFailureHeader::GetCause () const
+{
+ return m_cause;
+}
+
+void
+EpcX2HandoverPreparationFailureHeader::SetCause (uint16_t cause)
+{
+ m_cause = cause;
+}
+
+uint16_t
+EpcX2HandoverPreparationFailureHeader::GetCriticalityDiagnostics () const
+{
+ return m_criticalityDiagnostics;
+}
+
+void
+EpcX2HandoverPreparationFailureHeader::SetCriticalityDiagnostics (uint16_t criticalityDiagnostics)
+{
+ m_criticalityDiagnostics = criticalityDiagnostics;
+}
+
+uint32_t
+EpcX2HandoverPreparationFailureHeader::GetLengthOfIes () const
+{
+ return m_headerLength;
+}
+
+uint32_t
+EpcX2HandoverPreparationFailureHeader::GetNumberOfIes () const
+{
+ return m_numberOfIes;
+}
+
+/////////////////////////////////////////////////////////////////////
+
NS_OBJECT_ENSURE_REGISTERED (EpcX2UeContextReleaseHeader);
EpcX2UeContextReleaseHeader::EpcX2UeContextReleaseHeader ()
--- a/src/lte/model/epc-x2-header.h Mon Dec 03 17:48:23 2012 +0100
+++ b/src/lte/model/epc-x2-header.h Mon Dec 03 17:49:23 2012 +0100
@@ -135,7 +135,7 @@
public:
EpcX2HandoverRequestAckHeader ();
virtual ~EpcX2HandoverRequestAckHeader ();
-
+
static TypeId GetTypeId (void);
virtual TypeId GetInstanceTypeId (void) const;
virtual uint32_t GetSerializedSize (void) const;
@@ -170,6 +170,42 @@
};
+class EpcX2HandoverPreparationFailureHeader : public Header
+{
+public:
+ EpcX2HandoverPreparationFailureHeader ();
+ virtual ~EpcX2HandoverPreparationFailureHeader ();
+
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+
+
+ uint16_t GetOldEnbUeX2apId () const;
+ void SetOldEnbUeX2apId (uint16_t x2apId);
+
+ uint16_t GetCause () const;
+ void SetCause (uint16_t cause);
+
+ uint16_t GetCriticalityDiagnostics () const;
+ void SetCriticalityDiagnostics (uint16_t criticalityDiagnostics);
+
+ uint32_t GetLengthOfIes () const;
+ uint32_t GetNumberOfIes () const;
+
+private:
+ uint32_t m_numberOfIes;
+ uint32_t m_headerLength;
+
+ uint16_t m_oldEnbUeX2apId;
+ uint16_t m_cause;
+ uint16_t m_criticalityDiagnostics;
+};
+
+
class EpcX2UeContextReleaseHeader : public Header
{
public:
--- a/src/lte/model/epc-x2-sap.h Mon Dec 03 17:48:23 2012 +0100
+++ b/src/lte/model/epc-x2-sap.h Mon Dec 03 17:49:23 2012 +0100
@@ -234,6 +234,20 @@
};
/**
+ * \brief Parameters of the HANDOVER PREPARATION FAILURE message.
+ *
+ * See section 9.1.1.3 for further info about the parameters
+ */
+ struct HandoverPreparationFailureParams
+ {
+ uint16_t oldEnbUeX2apId;
+ uint16_t sourceCellId;
+ uint16_t targetCellId;
+ uint16_t cause;
+ uint16_t criticalityDiagnostics;
+ };
+
+ /**
* \brief Parameters of the UE CONTEXT RELEASE message.
*
* See section 9.1.1.5 for further info about the parameters
@@ -289,6 +303,8 @@
virtual void SendHandoverRequestAck (HandoverRequestAckParams params) = 0;
+ virtual void SendHandoverPreparationFailure (HandoverPreparationFailureParams params) = 0;
+
virtual void SendUeContextRelease (UeContextReleaseParams params) = 0;
virtual void SendLoadInformation (LoadInformationParams params) = 0;
@@ -314,6 +330,8 @@
virtual void RecvHandoverRequestAck (HandoverRequestAckParams params) = 0;
+ virtual void RecvHandoverPreparationFailure (HandoverPreparationFailureParams params) = 0;
+
virtual void RecvUeContextRelease (UeContextReleaseParams params) = 0;
virtual void RecvLoadInformation (LoadInformationParams params) = 0;
@@ -337,6 +355,8 @@
virtual void SendHandoverRequestAck (HandoverRequestAckParams params);
+ virtual void SendHandoverPreparationFailure (HandoverPreparationFailureParams params);
+
virtual void SendUeContextRelease (UeContextReleaseParams params);
virtual void SendLoadInformation (LoadInformationParams params);
@@ -375,6 +395,13 @@
template <class C>
void
+EpcX2SpecificEpcX2SapProvider<C>::SendHandoverPreparationFailure (HandoverPreparationFailureParams params)
+{
+ m_x2->DoSendHandoverPreparationFailure (params);
+}
+
+template <class C>
+void
EpcX2SpecificEpcX2SapProvider<C>::SendUeContextRelease (UeContextReleaseParams params)
{
m_x2->DoSendUeContextRelease (params);
@@ -410,6 +437,8 @@
virtual void RecvHandoverRequestAck (HandoverRequestAckParams params);
+ virtual void RecvHandoverPreparationFailure (HandoverPreparationFailureParams params);
+
virtual void RecvUeContextRelease (UeContextReleaseParams params);
virtual void RecvLoadInformation (LoadInformationParams params);
@@ -448,6 +477,13 @@
template <class C>
void
+EpcX2SpecificEpcX2SapUser<C>::RecvHandoverPreparationFailure (HandoverPreparationFailureParams params)
+{
+ m_rrc->DoRecvHandoverPreparationFailure (params);
+}
+
+template <class C>
+void
EpcX2SpecificEpcX2SapUser<C>::RecvUeContextRelease (UeContextReleaseParams params)
{
m_rrc->DoRecvUeContextRelease (params);
--- a/src/lte/model/epc-x2.cc Mon Dec 03 17:48:23 2012 +0100
+++ b/src/lte/model/epc-x2.cc Mon Dec 03 17:49:23 2012 +0100
@@ -211,7 +211,7 @@
m_x2SapUser->RecvHandoverRequest (params);
}
- else // messageType == SuccessfulOutcome
+ else if (messageType == EpcX2Header::SuccessfulOutcome)
{
NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST ACK");
@@ -238,6 +238,32 @@
m_x2SapUser->RecvHandoverRequestAck (params);
}
+ else // messageType == EpcX2Header::UnsuccessfulOutcome
+ {
+ NS_LOG_LOGIC ("Recv X2 message: HANDOVER PREPARATION FAILURE");
+
+ EpcX2HandoverPreparationFailureHeader x2HoPrepFailHeader;
+ packet->RemoveHeader (x2HoPrepFailHeader);
+
+ NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
+ "Missing infos of local and remote CellId");
+ Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
+
+ EpcX2SapUser::HandoverPreparationFailureParams params;
+ params.oldEnbUeX2apId = x2HoPrepFailHeader.GetOldEnbUeX2apId ();
+ params.sourceCellId = cellsInfo->m_localCellId;
+ params.targetCellId = cellsInfo->m_remoteCellId;
+ params.cause = x2HoPrepFailHeader.GetCause ();
+ params.criticalityDiagnostics = x2HoPrepFailHeader.GetCriticalityDiagnostics ();
+
+ NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+ NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
+ NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
+ NS_LOG_LOGIC ("cause = " << params.cause);
+ NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
+
+ m_x2SapUser->RecvHandoverPreparationFailure (params);
+ }
}
else if (procedureCode == EpcX2Header::LoadIndication)
{
@@ -412,6 +438,54 @@
void
+EpcX2::DoSendHandoverPreparationFailure (EpcX2SapProvider::HandoverPreparationFailureParams params)
+{
+ NS_LOG_FUNCTION (this);
+
+ NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+ NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
+ NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
+ NS_LOG_LOGIC ("cause = " << params.cause);
+ NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
+
+ NS_ASSERT_MSG (m_x2InterfaceSockets.find (params.sourceCellId) != m_x2InterfaceSockets.end (),
+ "Socket infos not defined for sourceCellId = " << params.sourceCellId);
+
+ Ptr<Socket> localSocket = m_x2InterfaceSockets [params.sourceCellId]->m_localSocket;
+ Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.sourceCellId]->m_remoteIpAddr;
+
+ NS_LOG_LOGIC ("localSocket = " << localSocket);
+ NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
+
+ NS_LOG_INFO ("Send X2 message: HANDOVER PREPARATION FAILURE");
+
+ // Build the X2 message
+ EpcX2HandoverPreparationFailureHeader x2HoPrepFailHeader;
+ x2HoPrepFailHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
+ x2HoPrepFailHeader.SetCause (params.cause);
+ x2HoPrepFailHeader.SetCriticalityDiagnostics (params.criticalityDiagnostics);
+
+ EpcX2Header x2Header;
+ x2Header.SetMessageType (EpcX2Header::UnsuccessfulOutcome);
+ x2Header.SetProcedureCode (EpcX2Header::HandoverPreparation);
+ x2Header.SetLengthOfIes (x2HoPrepFailHeader.GetLengthOfIes ());
+ x2Header.SetNumberOfIes (x2HoPrepFailHeader.GetNumberOfIes ());
+
+ NS_LOG_INFO ("X2 header: " << x2Header);
+ NS_LOG_INFO ("X2 HandoverPrepFail header: " << x2HoPrepFailHeader);
+
+ // Build the X2 packet
+ Ptr<Packet> packet = Create <Packet> ();
+ packet->AddHeader (x2HoPrepFailHeader);
+ packet->AddHeader (x2Header);
+ NS_LOG_INFO ("packetLen = " << packet->GetSize ());
+
+ // Send the X2 message through the socket
+ localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
+}
+
+
+void
EpcX2::DoSendUeContextRelease (EpcX2SapProvider::UeContextReleaseParams params)
{
NS_LOG_FUNCTION (this);
--- a/src/lte/model/epc-x2.h Mon Dec 03 17:48:23 2012 +0100
+++ b/src/lte/model/epc-x2.h Mon Dec 03 17:49:23 2012 +0100
@@ -115,6 +115,7 @@
// Interface provided by EpcX2SapProvider
virtual void DoSendHandoverRequest (EpcX2SapProvider::HandoverRequestParams params);
virtual void DoSendHandoverRequestAck (EpcX2SapProvider::HandoverRequestAckParams params);
+ virtual void DoSendHandoverPreparationFailure (EpcX2SapProvider::HandoverPreparationFailureParams params);
virtual void DoSendUeContextRelease (EpcX2SapProvider::UeContextReleaseParams params);
virtual void DoSendLoadInformation (EpcX2SapProvider::LoadInformationParams params);
virtual void DoSendResourceStatusUpdate (EpcX2SapProvider::ResourceStatusUpdateParams params);
--- a/src/lte/model/lte-enb-rrc.cc Mon Dec 03 17:48:23 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.cc Mon Dec 03 17:49:23 2012 +0100
@@ -1277,6 +1277,22 @@
}
void
+LteEnbRrc::DoRecvHandoverPreparationFailure (EpcX2SapUser::HandoverPreparationFailureParams params)
+{
+ NS_LOG_FUNCTION (this);
+
+ NS_LOG_LOGIC ("Recv X2 message: HANDOVER PREPARATION FAILURE");
+
+ NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+ NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
+ NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
+ NS_LOG_LOGIC ("cause = " << params.cause);
+ NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
+
+ NS_ASSERT ("Processing of HANDOVER PREPARATION FAILURE X2 message IS NOT IMPLEMENTED");
+}
+
+void
LteEnbRrc::DoRecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params)
{
NS_LOG_FUNCTION (this);
--- a/src/lte/model/lte-enb-rrc.h Mon Dec 03 17:48:23 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.h Mon Dec 03 17:49:23 2012 +0100
@@ -557,6 +557,7 @@
// X2 SAP methods
void DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params);
void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
+ void DoRecvHandoverPreparationFailure (EpcX2SapUser::HandoverPreparationFailureParams params);
void DoRecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params);
void DoRecvLoadInformation (EpcX2SapUser::LoadInformationParams params);
void DoRecvResourceStatusUpdate (EpcX2SapUser::ResourceStatusUpdateParams params);