diff --git a/src/lte/model/epc-x2-header.cc b/src/lte/model/epc-x2-header.cc index fede33811..fad96dcd6 100644 --- a/src/lte/model/epc-x2-header.cc +++ b/src/lte/model/epc-x2-header.cc @@ -658,6 +658,131 @@ EpcX2HandoverRequestAckHeader::GetNumberOfIes () const ///////////////////////////////////////////////////////////////////// +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
() + .AddConstructor () + ; + 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 () diff --git a/src/lte/model/epc-x2-header.h b/src/lte/model/epc-x2-header.h index 33cd6a7e5..776909e8b 100644 --- a/src/lte/model/epc-x2-header.h +++ b/src/lte/model/epc-x2-header.h @@ -135,7 +135,7 @@ class EpcX2HandoverRequestAckHeader : public Header public: EpcX2HandoverRequestAckHeader (); virtual ~EpcX2HandoverRequestAckHeader (); - + static TypeId GetTypeId (void); virtual TypeId GetInstanceTypeId (void) const; virtual uint32_t GetSerializedSize (void) const; @@ -170,6 +170,42 @@ private: }; +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: diff --git a/src/lte/model/epc-x2-sap.h b/src/lte/model/epc-x2-sap.h index c7914d604..294483052 100644 --- a/src/lte/model/epc-x2-sap.h +++ b/src/lte/model/epc-x2-sap.h @@ -233,6 +233,20 @@ public: Ptr rrcContext; }; + /** + * \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. * @@ -289,6 +303,8 @@ public: 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 @@ public: 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 @@ public: virtual void SendHandoverRequestAck (HandoverRequestAckParams params); + virtual void SendHandoverPreparationFailure (HandoverPreparationFailureParams params); + virtual void SendUeContextRelease (UeContextReleaseParams params); virtual void SendLoadInformation (LoadInformationParams params); @@ -373,6 +393,13 @@ EpcX2SpecificEpcX2SapProvider::SendHandoverRequestAck (HandoverRequestAckPara m_x2->DoSendHandoverRequestAck (params); } +template +void +EpcX2SpecificEpcX2SapProvider::SendHandoverPreparationFailure (HandoverPreparationFailureParams params) +{ + m_x2->DoSendHandoverPreparationFailure (params); +} + template void EpcX2SpecificEpcX2SapProvider::SendUeContextRelease (UeContextReleaseParams params) @@ -410,6 +437,8 @@ public: virtual void RecvHandoverRequestAck (HandoverRequestAckParams params); + virtual void RecvHandoverPreparationFailure (HandoverPreparationFailureParams params); + virtual void RecvUeContextRelease (UeContextReleaseParams params); virtual void RecvLoadInformation (LoadInformationParams params); @@ -446,6 +475,13 @@ EpcX2SpecificEpcX2SapUser::RecvHandoverRequestAck (HandoverRequestAckParams p m_rrc->DoRecvHandoverRequestAck (params); } +template +void +EpcX2SpecificEpcX2SapUser::RecvHandoverPreparationFailure (HandoverPreparationFailureParams params) +{ + m_rrc->DoRecvHandoverPreparationFailure (params); +} + template void EpcX2SpecificEpcX2SapUser::RecvUeContextRelease (UeContextReleaseParams params) diff --git a/src/lte/model/epc-x2.cc b/src/lte/model/epc-x2.cc index 2d9f8ce0f..77a63ff60 100644 --- a/src/lte/model/epc-x2.cc +++ b/src/lte/model/epc-x2.cc @@ -211,7 +211,7 @@ EpcX2::RecvFromX2cSocket (Ptr socket) 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 @@ EpcX2::RecvFromX2cSocket (Ptr socket) 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 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) { @@ -411,6 +437,54 @@ EpcX2::DoSendHandoverRequestAck (EpcX2SapProvider::HandoverRequestAckParams para } +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 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 = Create (); + 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) { diff --git a/src/lte/model/epc-x2.h b/src/lte/model/epc-x2.h index 12954d9c4..3c25ca579 100644 --- a/src/lte/model/epc-x2.h +++ b/src/lte/model/epc-x2.h @@ -115,6 +115,7 @@ protected: // 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); diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc index 89cb23f95..caa0931f9 100644 --- a/src/lte/model/lte-enb-rrc.cc +++ b/src/lte/model/lte-enb-rrc.cc @@ -1276,6 +1276,22 @@ LteEnbRrc::DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams para } +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) { diff --git a/src/lte/model/lte-enb-rrc.h b/src/lte/model/lte-enb-rrc.h index 19bd3778d..28e2ebbc5 100644 --- a/src/lte/model/lte-enb-rrc.h +++ b/src/lte/model/lte-enb-rrc.h @@ -557,6 +557,7 @@ private: // 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);