This commit is contained in:
Manuel Requena
2012-11-27 19:06:57 +01:00
7 changed files with 416 additions and 19 deletions

View File

@@ -970,5 +970,182 @@ EpcX2LoadInformationHeader::GetNumberOfIes () const
return m_numberOfIes;
}
////////////////
NS_OBJECT_ENSURE_REGISTERED (EpcX2ResourceStatusUpdateHeader);
EpcX2ResourceStatusUpdateHeader::EpcX2ResourceStatusUpdateHeader ()
: m_numberOfIes (3),
m_headerLength (6),
m_enb1MeasurementId (0),
m_enb2MeasurementId (0)
{
m_cellMeasurementResultList.clear ();
}
EpcX2ResourceStatusUpdateHeader::~EpcX2ResourceStatusUpdateHeader ()
{
m_numberOfIes = 0;
m_headerLength = 0;
m_enb1MeasurementId = 0;
m_enb2MeasurementId = 0;
m_cellMeasurementResultList.clear ();
}
TypeId
EpcX2ResourceStatusUpdateHeader::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::EpcX2ResourceStatusUpdateHeader")
.SetParent<Header> ()
.AddConstructor<EpcX2ResourceStatusUpdateHeader> ()
;
return tid;
}
TypeId
EpcX2ResourceStatusUpdateHeader::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
uint32_t
EpcX2ResourceStatusUpdateHeader::GetSerializedSize (void) const
{
return m_headerLength;
}
void
EpcX2ResourceStatusUpdateHeader::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
i.WriteHtonU16 (m_enb1MeasurementId);
i.WriteHtonU16 (m_enb2MeasurementId);
std::vector <EpcX2Sap::CellMeasurementResultItem>::size_type sz = m_cellMeasurementResultList.size ();
i.WriteHtonU16 (sz); // number of CellMeasurementResultItem
for (int j = 0; j < (int) sz; j++)
{
EpcX2Sap::CellMeasurementResultItem item = m_cellMeasurementResultList [j];
i.WriteHtonU16 (item.sourceCellId);
i.WriteU8 (item.dlHardwareLoadIndicator);
i.WriteU8 (item.ulHardwareLoadIndicator);
i.WriteU8 (item.dlS1TnlLoadIndicator);
i.WriteU8 (item.ulS1TnlLoadIndicator);
i.WriteHtonU16 (item.dlGbrPrbUsage);
i.WriteHtonU16 (item.ulGbrPrbUsage);
i.WriteHtonU16 (item.dlNonGbrPrbUsage);
i.WriteHtonU16 (item.ulNonGbrPrbUsage);
i.WriteHtonU16 (item.dlTotalPrbUsage);
i.WriteHtonU16 (item.ulTotalPrbUsage);
i.WriteHtonU16 (item.dlCompositeAvailableCapacity.cellCapacityClassValue);
i.WriteHtonU16 (item.dlCompositeAvailableCapacity.capacityValue);
i.WriteHtonU16 (item.ulCompositeAvailableCapacity.cellCapacityClassValue);
i.WriteHtonU16 (item.ulCompositeAvailableCapacity.capacityValue);
}
}
uint32_t
EpcX2ResourceStatusUpdateHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
m_enb1MeasurementId = i.ReadNtohU16 ();
m_enb2MeasurementId = i.ReadNtohU16 ();
int sz = i.ReadNtohU16 ();
for (int j = 0; j < sz; j++)
{
EpcX2Sap::CellMeasurementResultItem item;
item.sourceCellId = i.ReadNtohU16 ();
item.dlHardwareLoadIndicator = (EpcX2Sap::LoadIndicator) i.ReadU8 ();
item.ulHardwareLoadIndicator = (EpcX2Sap::LoadIndicator) i.ReadU8 ();
item.dlS1TnlLoadIndicator = (EpcX2Sap::LoadIndicator) i.ReadU8 ();
item.ulS1TnlLoadIndicator = (EpcX2Sap::LoadIndicator) i.ReadU8 ();
item.dlGbrPrbUsage = i.ReadNtohU16 ();
item.ulGbrPrbUsage = i.ReadNtohU16 ();
item.dlNonGbrPrbUsage = i.ReadNtohU16 ();
item.ulNonGbrPrbUsage = i.ReadNtohU16 ();
item.dlTotalPrbUsage = i.ReadNtohU16 ();
item.ulTotalPrbUsage = i.ReadNtohU16 ();
item.dlCompositeAvailableCapacity.cellCapacityClassValue = i.ReadNtohU16 ();
item.dlCompositeAvailableCapacity.capacityValue = i.ReadNtohU16 ();
item.ulCompositeAvailableCapacity.cellCapacityClassValue = i.ReadNtohU16 ();
item.ulCompositeAvailableCapacity.capacityValue = i.ReadNtohU16 ();
m_cellMeasurementResultList.push_back (item);
}
m_headerLength = 6 + sz * 26;
m_numberOfIes = 3;
return GetSerializedSize ();
}
void
EpcX2ResourceStatusUpdateHeader::Print (std::ostream &os) const
{
os << "Enb1MeasurementId = " << m_enb1MeasurementId
<< " Enb2MeasurementId = " << m_enb2MeasurementId
<< " NumOfCellMeasurementResultItems = " << m_cellMeasurementResultList.size ();
}
uint16_t
EpcX2ResourceStatusUpdateHeader::GetEnb1MeasurementId () const
{
return m_enb1MeasurementId;
}
void
EpcX2ResourceStatusUpdateHeader::SetEnb1MeasurementId (uint16_t enb1MeasurementId)
{
m_enb1MeasurementId = enb1MeasurementId;
}
uint16_t
EpcX2ResourceStatusUpdateHeader::GetEnb2MeasurementId () const
{
return m_enb2MeasurementId;
}
void
EpcX2ResourceStatusUpdateHeader::SetEnb2MeasurementId (uint16_t enb2MeasurementId)
{
m_enb2MeasurementId = enb2MeasurementId;
}
std::vector <EpcX2Sap::CellMeasurementResultItem>
EpcX2ResourceStatusUpdateHeader::GetCellMeasurementResultList () const
{
return m_cellMeasurementResultList;
}
void
EpcX2ResourceStatusUpdateHeader::SetCellMeasurementResultList (std::vector <EpcX2Sap::CellMeasurementResultItem> cellMeasurementResultList)
{
m_cellMeasurementResultList = cellMeasurementResultList;
std::vector <EpcX2Sap::CellMeasurementResultItem>::size_type sz = m_cellMeasurementResultList.size ();
m_headerLength += sz * 26;
}
uint32_t
EpcX2ResourceStatusUpdateHeader::GetLengthOfIes () const
{
return m_headerLength;
}
uint32_t
EpcX2ResourceStatusUpdateHeader::GetNumberOfIes () const
{
return m_numberOfIes;
}
} // namespace ns3

View File

@@ -56,8 +56,9 @@ public:
enum ProcedureCode_t {
HandoverPreparation = 0,
LoadInformation = 2,
UeContextRelease = 5
LoadIndication = 2,
UeContextRelease = 5,
ResourceStatusReporting = 10
};
enum TypeOfMessage_t {
@@ -225,6 +226,42 @@ private:
};
class EpcX2ResourceStatusUpdateHeader : public Header
{
public:
EpcX2ResourceStatusUpdateHeader ();
virtual ~EpcX2ResourceStatusUpdateHeader ();
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 GetEnb1MeasurementId () const;
void SetEnb1MeasurementId (uint16_t enb1MeasurementId);
uint16_t GetEnb2MeasurementId () const;
void SetEnb2MeasurementId (uint16_t enb2MeasurementId);
std::vector <EpcX2Sap::CellMeasurementResultItem> GetCellMeasurementResultList () const;
void SetCellMeasurementResultList (std::vector <EpcX2Sap::CellMeasurementResultItem> cellMeasurementResultList);
uint32_t GetLengthOfIes () const;
uint32_t GetNumberOfIes () const;
private:
uint32_t m_numberOfIes;
uint32_t m_headerLength;
uint16_t m_enb1MeasurementId;
uint16_t m_enb2MeasurementId;
std::vector <EpcX2Sap::CellMeasurementResultItem> m_cellMeasurementResultList;
};
} // namespace ns3
#endif // EPC_X2_HEADER_H

View File

@@ -61,7 +61,7 @@ public:
bool dlForwarding;
Ipv4Address transportLayerAddress;
uint32_t gtpTeid;
ErabToBeSetupItem ();
};
@@ -76,7 +76,7 @@ public:
uint32_t ulGtpTeid;
uint32_t dlGtpTeid;
};
/**
* E-RABs not admitted item as
* it is used in the HANDOVER REQUEST ACKNOWLEDGE message.
@@ -141,6 +141,56 @@ public:
RelativeNarrowbandTxBand relativeNarrowbandTxBand;
};
/**
* Load Indicator as
* it is used in the RESOURCE STATUS UPDATE message.
* See section 9.2.36 for further info about the value
*/
enum LoadIndicator
{
LowLoad,
MediumLoad,
HighLoad,
Overload
};
/**
* Composite Available Capacity as
* it is used in the RESOURCE STATUS UPDATE message.
* See section 9.2.45 for further info about the parameters
*/
struct CompositeAvailCapacity
{
uint16_t cellCapacityClassValue;
uint16_t capacityValue;
};
/**
* Cell Measurement Result Item as
* it is used in the RESOURCE STATUS UPDATE message.
* See section 9.1.2.14 for further info about the parameters
*/
struct CellMeasurementResultItem
{
uint16_t sourceCellId;
LoadIndicator dlHardwareLoadIndicator;
LoadIndicator ulHardwareLoadIndicator;
LoadIndicator dlS1TnlLoadIndicator;
LoadIndicator ulS1TnlLoadIndicator;
uint16_t dlGbrPrbUsage;
uint16_t ulGbrPrbUsage;
uint16_t dlNonGbrPrbUsage;
uint16_t ulNonGbrPrbUsage;
uint16_t dlTotalPrbUsage;
uint16_t ulTotalPrbUsage;
CompositeAvailCapacity dlCompositeAvailableCapacity;
CompositeAvailCapacity ulCompositeAvailableCapacity;
};
enum IdCause
{
@@ -165,7 +215,7 @@ public:
std::vector <ErabToBeSetupItem> bearers;
Ptr<Packet> rrcContext;
};
/**
* \brief Parameters of the HANDOVER REQUEST ACKNOWLEDGE message.
*
@@ -205,6 +255,19 @@ public:
std::vector <CellInformationItem> cellInformationList;
};
/**
* \brief Parameters of the RESOURCE STATUS UPDATE message.
*
* See section 9.1.2.14 for further info about the parameters
*/
struct ResourceStatusUpdateParams
{
uint16_t targetCellId;
uint16_t enb1MeasurementId;
uint16_t enb2MeasurementId;
std::vector <CellMeasurementResultItem> cellMeasurementResultList;
};
};
@@ -216,7 +279,7 @@ class EpcX2SapProvider : public EpcX2Sap
{
public:
virtual ~EpcX2SapProvider ();
/**
* Service primitives
*/
@@ -228,6 +291,8 @@ public:
virtual void SendUeContextRelease (UeContextReleaseParams params) = 0;
virtual void SendLoadInformation (LoadInformationParams params) = 0;
virtual void SendResourceStatusUpdate (ResourceStatusUpdateParams params) = 0;
};
@@ -251,6 +316,8 @@ public:
virtual void RecvUeContextRelease (UeContextReleaseParams params) = 0;
virtual void RecvLoadInformation (LoadInformationParams params) = 0;
virtual void RecvResourceStatusUpdate (ResourceStatusUpdateParams params) = 0;
};
///////////////////////////////////////
@@ -272,7 +339,9 @@ public:
virtual void SendUeContextRelease (UeContextReleaseParams params);
virtual void SendLoadInformation (LoadInformationParams params);
virtual void SendResourceStatusUpdate (ResourceStatusUpdateParams params);
private:
EpcX2SpecificEpcX2SapProvider ();
C* m_x2;
@@ -317,6 +386,13 @@ EpcX2SpecificEpcX2SapProvider<C>::SendLoadInformation (LoadInformationParams par
m_x2->DoSendLoadInformation (params);
}
template <class C>
void
EpcX2SpecificEpcX2SapProvider<C>::SendResourceStatusUpdate (ResourceStatusUpdateParams params)
{
m_x2->DoSendResourceStatusUpdate (params);
}
///////////////////////////////////////
template <class C>
@@ -332,11 +408,13 @@ public:
virtual void RecvHandoverRequest (HandoverRequestParams params);
virtual void RecvHandoverRequestAck (HandoverRequestAckParams params);
virtual void RecvUeContextRelease (UeContextReleaseParams params);
virtual void RecvLoadInformation (LoadInformationParams params);
virtual void RecvResourceStatusUpdate (ResourceStatusUpdateParams params);
private:
EpcX2SpecificEpcX2SapUser ();
C* m_rrc;
@@ -381,6 +459,13 @@ EpcX2SpecificEpcX2SapUser<C>::RecvLoadInformation (LoadInformationParams params)
m_rrc->DoRecvLoadInformation (params);
}
template <class C>
void
EpcX2SpecificEpcX2SapUser<C>::RecvResourceStatusUpdate (ResourceStatusUpdateParams params)
{
m_rrc->DoRecvResourceStatusUpdate (params);
}
} // namespace ns3
#endif // EPC_X2_SAP_H

View File

@@ -40,6 +40,7 @@ X2IfaceInfo::X2IfaceInfo (Ptr<Socket> localSocket, Ipv4Address remoteIpAddr)
X2IfaceInfo::~X2IfaceInfo (void)
{
m_localSocket = 0;
}
X2IfaceInfo&
@@ -61,6 +62,8 @@ X2CellInfo::X2CellInfo (uint16_t localCellId, uint16_t remoteCellId)
X2CellInfo::~X2CellInfo (void)
{
m_localCellId = 0;
m_remoteCellId = 0;
}
X2CellInfo&
@@ -80,10 +83,25 @@ EpcX2::EpcX2 ()
: m_x2cUdpPort (4444)
{
NS_LOG_FUNCTION (this);
m_x2SapProvider = new EpcX2SpecificEpcX2SapProvider<EpcX2> (this);
}
EpcX2::~EpcX2 ()
{
NS_LOG_FUNCTION (this);
}
void
EpcX2::DoDispose (void)
{
NS_LOG_FUNCTION (this);
m_x2InterfaceSockets.clear ();
m_x2InterfaceCellIds.clear ();
delete m_x2SapProvider;
}
TypeId
EpcX2::GetTypeId (void)
{
@@ -92,12 +110,6 @@ EpcX2::GetTypeId (void)
return tid;
}
EpcX2::~EpcX2 (void)
{
NS_LOG_FUNCTION (this);
delete m_x2SapProvider;
}
void
EpcX2::SetEpcX2SapUser (EpcX2SapUser * s)
{
@@ -225,7 +237,7 @@ EpcX2::RecvFromX2cSocket (Ptr<Socket> socket)
m_x2SapUser->RecvHandoverRequestAck (params);
}
}
else if (procedureCode == EpcX2Header::LoadInformation)
else if (procedureCode == EpcX2Header::LoadIndication)
{
if (messageType == EpcX2Header::InitiatingMessage)
{
@@ -265,6 +277,29 @@ EpcX2::RecvFromX2cSocket (Ptr<Socket> socket)
m_x2SapUser->RecvUeContextRelease (params);
}
}
else if (procedureCode == EpcX2Header::ResourceStatusReporting)
{
if (messageType == EpcX2Header::InitiatingMessage)
{
NS_LOG_LOGIC ("Recv X2 message: RESOURCE STATUS UPDATE");
EpcX2ResourceStatusUpdateHeader x2ResStatUpdHeader;
packet->RemoveHeader (x2ResStatUpdHeader);
NS_LOG_INFO ("X2 ResourceStatusUpdate header: " << x2ResStatUpdHeader);
EpcX2SapUser::ResourceStatusUpdateParams params;
params.enb1MeasurementId = x2ResStatUpdHeader.GetEnb1MeasurementId ();
params.enb2MeasurementId = x2ResStatUpdHeader.GetEnb2MeasurementId ();
params.cellMeasurementResultList = x2ResStatUpdHeader.GetCellMeasurementResultList ();
NS_LOG_LOGIC ("enb1MeasurementId = " << params.enb1MeasurementId);
NS_LOG_LOGIC ("enb2MeasurementId = " << params.enb2MeasurementId);
NS_LOG_LOGIC ("cellMeasurementResultList size = " << params.cellMeasurementResultList.size ());
m_x2SapUser->RecvResourceStatusUpdate (params);
}
}
else
{
NS_ASSERT_MSG (false, "ProcedureCode NOT SUPPORTED!!!");
@@ -442,7 +477,7 @@ EpcX2::DoSendLoadInformation (EpcX2SapProvider::LoadInformationParams params)
EpcX2Header x2Header;
x2Header.SetMessageType (EpcX2Header::InitiatingMessage);
x2Header.SetProcedureCode (EpcX2Header::LoadInformation);
x2Header.SetProcedureCode (EpcX2Header::LoadIndication);
x2Header.SetLengthOfIes (x2LoadInfoHeader.GetLengthOfIes ());
x2Header.SetNumberOfIes (x2LoadInfoHeader.GetNumberOfIes ());
@@ -461,4 +496,52 @@ EpcX2::DoSendLoadInformation (EpcX2SapProvider::LoadInformationParams params)
}
void
EpcX2::DoSendResourceStatusUpdate (EpcX2SapProvider::ResourceStatusUpdateParams params)
{
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
NS_LOG_LOGIC ("enb1MeasurementId = " << params.enb1MeasurementId);
NS_LOG_LOGIC ("enb2MeasurementId = " << params.enb2MeasurementId);
NS_LOG_LOGIC ("cellMeasurementResultList size = " << params.cellMeasurementResultList.size ());
NS_ASSERT_MSG (m_x2InterfaceSockets.find (params.targetCellId) != m_x2InterfaceSockets.end (),
"Missing infos for targetCellId = " << params.targetCellId);
Ptr<X2IfaceInfo> socketInfo = m_x2InterfaceSockets [params.targetCellId];
Ptr<Socket> sourceSocket = socketInfo->m_localSocket;
Ipv4Address targetIpAddr = socketInfo->m_remoteIpAddr;
NS_LOG_LOGIC ("sourceSocket = " << sourceSocket);
NS_LOG_LOGIC ("targetIpAddr = " << targetIpAddr);
NS_LOG_INFO ("Send X2 message: RESOURCE STATUS UPDATE");
// Build the X2 message
EpcX2ResourceStatusUpdateHeader x2ResourceStatUpdHeader;
x2ResourceStatUpdHeader.SetEnb1MeasurementId (params.enb1MeasurementId);
x2ResourceStatUpdHeader.SetEnb2MeasurementId (params.enb2MeasurementId);
x2ResourceStatUpdHeader.SetCellMeasurementResultList (params.cellMeasurementResultList);
EpcX2Header x2Header;
x2Header.SetMessageType (EpcX2Header::InitiatingMessage);
x2Header.SetProcedureCode (EpcX2Header::ResourceStatusReporting);
x2Header.SetLengthOfIes (x2ResourceStatUpdHeader.GetLengthOfIes ());
x2Header.SetNumberOfIes (x2ResourceStatUpdHeader.GetNumberOfIes ());
NS_LOG_INFO ("X2 header: " << x2Header);
NS_LOG_INFO ("X2 ResourceStatusUpdate header: " << x2ResourceStatUpdHeader);
// Build the X2 packet
Ptr<Packet> packet = Create <Packet> ();
packet->AddHeader (x2ResourceStatUpdHeader);
packet->AddHeader (x2Header);
NS_LOG_INFO ("packetLen = " << packet->GetSize ());
// Send the X2 message through the socket
sourceSocket->SendTo (packet, 0, InetSocketAddress (targetIpAddr, m_x2cUdpPort));
}
} // namespace ns3

View File

@@ -82,6 +82,7 @@ public:
virtual ~EpcX2 (void);
static TypeId GetTypeId (void);
virtual void DoDispose (void);
/**
@@ -111,11 +112,12 @@ public:
protected:
// Interface provided by LteRlcSapProvider
// Interface provided by EpcX2SapProvider
virtual void DoSendHandoverRequest (EpcX2SapProvider::HandoverRequestParams params);
virtual void DoSendHandoverRequestAck (EpcX2SapProvider::HandoverRequestAckParams params);
virtual void DoSendUeContextRelease (EpcX2SapProvider::UeContextReleaseParams params);
virtual void DoSendLoadInformation (EpcX2SapProvider::LoadInformationParams params);
virtual void DoSendResourceStatusUpdate (EpcX2SapProvider::ResourceStatusUpdateParams params);
EpcX2SapUser* m_x2SapUser;
EpcX2SapProvider* m_x2SapProvider;

View File

@@ -1232,6 +1232,18 @@ LteEnbRrc::DoRecvLoadInformation (EpcX2SapUser::LoadInformationParams params)
NS_ASSERT ("Processing of LOAD INFORMATION X2 message IS NOT IMPLEMENTED");
}
void
LteEnbRrc::DoRecvResourceStatusUpdate (EpcX2SapUser::ResourceStatusUpdateParams params)
{
NS_LOG_FUNCTION (this);
NS_LOG_LOGIC ("Recv X2 message: RESOURCE STATUS UPDATE");
NS_LOG_LOGIC ("Number of cellMeasurementResultItems = " << params.cellMeasurementResultList.size ());
NS_ASSERT ("Processing of RESOURCE STATUS UPDATE X2 message IS NOT IMPLEMENTED");
}
uint16_t
LteEnbRrc::DoAllocateTemporaryCellRnti ()

View File

@@ -544,7 +544,8 @@ private:
void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
void DoRecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params);
void DoRecvLoadInformation (EpcX2SapUser::LoadInformationParams params);
void DoRecvResourceStatusUpdate (EpcX2SapUser::ResourceStatusUpdateParams params);
// CMAC SAP methods
uint16_t DoAllocateTemporaryCellRnti ();