Add UE Context Release X2 message
This commit is contained in:
@@ -533,5 +533,94 @@ EpcX2HandoverRequestAckHeader::SetNotAdmittedBearers (std::vector <EpcX2Sap::Era
|
||||
m_erabsNotAdmittedList = bearers;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (EpcX2UeContextReleaseHeader);
|
||||
|
||||
EpcX2UeContextReleaseHeader::EpcX2UeContextReleaseHeader ()
|
||||
: m_oldEnbUeX2apId (0xfffa),
|
||||
m_newEnbUeX2apId (0xfffa)
|
||||
{
|
||||
}
|
||||
|
||||
EpcX2UeContextReleaseHeader::~EpcX2UeContextReleaseHeader ()
|
||||
{
|
||||
m_oldEnbUeX2apId = 0xfffb;
|
||||
m_newEnbUeX2apId = 0xfffb;
|
||||
}
|
||||
|
||||
TypeId
|
||||
EpcX2UeContextReleaseHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::EpcX2UeContextReleaseHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<EpcX2UeContextReleaseHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
EpcX2UeContextReleaseHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EpcX2UeContextReleaseHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
void
|
||||
EpcX2UeContextReleaseHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
i.WriteHtonU16 (m_oldEnbUeX2apId);
|
||||
i.WriteHtonU16 (m_newEnbUeX2apId);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
EpcX2UeContextReleaseHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
m_oldEnbUeX2apId = i.ReadNtohU16 ();
|
||||
m_newEnbUeX2apId = i.ReadNtohU16 ();
|
||||
|
||||
return GetSerializedSize ();
|
||||
}
|
||||
|
||||
void
|
||||
EpcX2UeContextReleaseHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "OldEnbUeX2apId=" << m_oldEnbUeX2apId;
|
||||
os << " NewEnbUeX2apId=" << m_newEnbUeX2apId;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
EpcX2UeContextReleaseHeader::GetOldEnbUeX2apId () const
|
||||
{
|
||||
return m_oldEnbUeX2apId;
|
||||
}
|
||||
|
||||
void
|
||||
EpcX2UeContextReleaseHeader::SetOldEnbUeX2apId (uint16_t x2apId)
|
||||
{
|
||||
m_oldEnbUeX2apId = x2apId;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
EpcX2UeContextReleaseHeader::GetNewEnbUeX2apId () const
|
||||
{
|
||||
return m_newEnbUeX2apId;
|
||||
}
|
||||
|
||||
void
|
||||
EpcX2UeContextReleaseHeader::SetNewEnbUeX2apId (uint16_t x2apId)
|
||||
{
|
||||
m_newEnbUeX2apId = x2apId;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -55,7 +55,8 @@ public:
|
||||
|
||||
|
||||
enum ProcedureCode_t {
|
||||
HandoverPreparation = 0
|
||||
HandoverPreparation = 0,
|
||||
UeContextRelease = 5
|
||||
};
|
||||
|
||||
enum TypeOfMessage_t {
|
||||
@@ -157,6 +158,31 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class EpcX2UeContextReleaseHeader : public Header
|
||||
{
|
||||
public:
|
||||
EpcX2UeContextReleaseHeader ();
|
||||
virtual ~EpcX2UeContextReleaseHeader ();
|
||||
|
||||
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 GetNewEnbUeX2apId () const;
|
||||
void SetNewEnbUeX2apId (uint16_t x2apId);
|
||||
|
||||
private:
|
||||
uint16_t m_oldEnbUeX2apId;
|
||||
uint16_t m_newEnbUeX2apId;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif // EPC_X2_HEADER_H
|
||||
|
||||
@@ -189,11 +189,17 @@ EpcX2::RecvFromX2cSocket (Ptr<Socket> socket)
|
||||
params.rrcContext = packet;
|
||||
|
||||
NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
|
||||
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
|
||||
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
|
||||
NS_LOG_LOGIC ("cellsInfo->m_localCellId = " << cellsInfo->m_localCellId);
|
||||
NS_ASSERT_MSG (params.targetCellId == cellsInfo->m_localCellId,
|
||||
"TargetCellId mismatches with localCellId");
|
||||
|
||||
// Map oldEnbUeX2apId to sourceCellId
|
||||
NS_ASSERT_MSG (m_x2Ues.find (params.oldEnbUeX2apId) == m_x2Ues.end (),
|
||||
"UE already in CellId. enbUeX2apId = " << params.oldEnbUeX2apId << ". CellId = " << params.sourceCellId);
|
||||
m_x2Ues [params.oldEnbUeX2apId] = params.sourceCellId;
|
||||
|
||||
m_x2SapUser->RecvHandoverRequest (params);
|
||||
}
|
||||
else // messageType == SuccessfulOutcome
|
||||
@@ -224,6 +230,27 @@ EpcX2::RecvFromX2cSocket (Ptr<Socket> socket)
|
||||
m_x2SapUser->RecvHandoverRequestAck (params);
|
||||
}
|
||||
}
|
||||
else // procedureCode == EpcX2Header::HandoverPreparation
|
||||
{
|
||||
if (messageType == EpcX2Header::InitiatingMessage)
|
||||
{
|
||||
NS_LOG_LOGIC ("Recv X2 message: UE CONTEXT RELEASE");
|
||||
|
||||
EpcX2UeContextReleaseHeader x2UeCtxReleaseHeader;
|
||||
packet->RemoveHeader (x2UeCtxReleaseHeader);
|
||||
|
||||
NS_LOG_INFO ("X2 UeContextRelease header: " << x2UeCtxReleaseHeader);
|
||||
|
||||
EpcX2SapUser::UeContextReleaseParams params;
|
||||
params.oldEnbUeX2apId = x2UeCtxReleaseHeader.GetOldEnbUeX2apId ();
|
||||
params.newEnbUeX2apId = x2UeCtxReleaseHeader.GetNewEnbUeX2apId ();
|
||||
|
||||
NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
|
||||
NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
|
||||
|
||||
m_x2SapUser->RecvUeContextRelease (params);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -247,7 +274,12 @@ EpcX2::DoSendHandoverRequest (EpcX2SapProvider::HandoverRequestParams params)
|
||||
|
||||
NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
|
||||
NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
|
||||
|
||||
|
||||
// Map oldEnbUeX2apId to sourceCellId
|
||||
NS_ASSERT_MSG (m_x2Ues.find (params.oldEnbUeX2apId) == m_x2Ues.end (),
|
||||
"UE already in CellId. enbUeX2apId = " << params.oldEnbUeX2apId << ". CellId = " << params.sourceCellId);
|
||||
m_x2Ues [params.oldEnbUeX2apId] = params.sourceCellId;
|
||||
|
||||
NS_LOG_INFO ("Send X2 message: HANDOVER REQUEST");
|
||||
|
||||
// Build the X2 message
|
||||
@@ -326,4 +358,52 @@ EpcX2::DoSendHandoverRequestAck (EpcX2SapProvider::HandoverRequestAckParams para
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EpcX2::DoSendUeContextRelease (EpcX2SapProvider::UeContextReleaseParams params)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
|
||||
NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
|
||||
|
||||
NS_ASSERT_MSG (m_x2Ues.find (params.oldEnbUeX2apId) != m_x2Ues.end (),
|
||||
"Missing CellId for enbUeX2apId = " << params.oldEnbUeX2apId);
|
||||
uint16_t sourceCellId = m_x2Ues [params.oldEnbUeX2apId];
|
||||
|
||||
NS_LOG_LOGIC ("sourceCellId = " << sourceCellId);
|
||||
|
||||
NS_ASSERT_MSG (m_x2InterfaceSockets.find (sourceCellId) != m_x2InterfaceSockets.end (),
|
||||
"Socket infos not defined for sourceCellId = " << sourceCellId);
|
||||
|
||||
Ptr<Socket> localSocket = m_x2InterfaceSockets [sourceCellId]->m_localSocket;
|
||||
Ipv4Address remoteIpAddr = m_x2InterfaceSockets [sourceCellId]->m_remoteIpAddr;
|
||||
|
||||
NS_LOG_LOGIC ("localSocket = " << localSocket);
|
||||
NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
|
||||
|
||||
NS_LOG_INFO ("Send X2 message: UE CONTEXT RELEASE");
|
||||
|
||||
// Build the X2 message
|
||||
EpcX2Header x2Header;
|
||||
x2Header.SetMessageType (EpcX2Header::InitiatingMessage);
|
||||
x2Header.SetProcedureCode (EpcX2Header::UeContextRelease);
|
||||
|
||||
EpcX2UeContextReleaseHeader x2UeCtxReleaseHeader;
|
||||
x2UeCtxReleaseHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
|
||||
x2UeCtxReleaseHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
|
||||
|
||||
NS_LOG_INFO ("X2 header: " << x2Header);
|
||||
NS_LOG_INFO ("X2 UeContextRelease header: " << x2UeCtxReleaseHeader);
|
||||
|
||||
// Build the X2 packet
|
||||
Ptr<Packet> packet = Create <Packet> ();
|
||||
packet->AddHeader (x2UeCtxReleaseHeader);
|
||||
packet->AddHeader (x2Header);
|
||||
NS_LOG_INFO ("packetLen = " << packet->GetSize ());
|
||||
|
||||
// Send the X2 message through the socket
|
||||
localSocket->SendTo (packet, 0, InetSocketAddress (remoteIpAddr, m_x2cUdpPort));
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -112,6 +112,7 @@ protected:
|
||||
// Interface provided by LteRlcSapProvider
|
||||
virtual void DoSendHandoverRequest (EpcX2SapProvider::HandoverRequestParams params);
|
||||
virtual void DoSendHandoverRequestAck (EpcX2SapProvider::HandoverRequestAckParams params);
|
||||
virtual void DoSendUeContextRelease (EpcX2SapProvider::UeContextReleaseParams params);
|
||||
|
||||
EpcX2SapUser* m_x2SapUser;
|
||||
EpcX2SapProvider* m_x2SapProvider;
|
||||
@@ -119,6 +120,11 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Map the enbUeX2apId to the corresponding cellId where the UE is camping on
|
||||
*/
|
||||
std::map < uint16_t, uint16_t > m_x2Ues;
|
||||
|
||||
/**
|
||||
* Map the targetCellId to the corresponding (sourceSocket, remoteIpAddr) to be used
|
||||
* to send the X2 message
|
||||
|
||||
Reference in New Issue
Block a user