merge
authorManuel Requena <manuel.requena@cttc.es>
Wed, 05 Dec 2012 13:52:42 +0100
changeset 9480 55db96d61f2c
parent 9475 fd37f7e77d9e (current diff)
parent 9479 a647c4d9b6e7 (diff)
child 9481 b828554155ff
merge
src/lte/model/epc-x2-header.cc
src/lte/model/epc-x2-header.h
src/lte/model/epc-x2-sap.h
src/lte/model/epc-x2.cc
src/lte/model/lte-enb-rrc.cc
src/lte/model/lte-enb-rrc.h
--- a/src/lte/model/epc-x2-header.cc	Wed Dec 05 13:43:21 2012 +0100
+++ b/src/lte/model/epc-x2-header.cc	Wed Dec 05 13:52:42 2012 +0100
@@ -783,6 +783,198 @@
 
 /////////////////////////////////////////////////////////////////////
 
+NS_OBJECT_ENSURE_REGISTERED (EpcX2SnStatusTransferHeader);
+
+EpcX2SnStatusTransferHeader::EpcX2SnStatusTransferHeader ()
+  : m_numberOfIes (3),
+    m_headerLength (6),
+    m_oldEnbUeX2apId (0xfffa),
+    m_newEnbUeX2apId (0xfffa)
+{
+  m_erabsSubjectToStatusTransferList.clear (); 
+}
+
+EpcX2SnStatusTransferHeader::~EpcX2SnStatusTransferHeader ()
+{
+  m_numberOfIes = 0;
+  m_headerLength = 0;
+  m_oldEnbUeX2apId = 0xfffb;
+  m_newEnbUeX2apId = 0xfffb;
+  m_erabsSubjectToStatusTransferList.clear (); 
+}
+
+TypeId
+EpcX2SnStatusTransferHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::EpcX2SnStatusTransferHeader")
+    .SetParent<Header> ()
+    .AddConstructor<EpcX2SnStatusTransferHeader> ()
+  ;
+  return tid;
+}
+
+TypeId
+EpcX2SnStatusTransferHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::GetSerializedSize (void) const
+{
+  return m_headerLength;
+}
+
+void
+EpcX2SnStatusTransferHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+
+  i.WriteHtonU16 (m_oldEnbUeX2apId);
+  i.WriteHtonU16 (m_newEnbUeX2apId);
+
+  std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem>::size_type sz = m_erabsSubjectToStatusTransferList.size ();
+  i.WriteHtonU16 (sz);              // number of ErabsSubjectToStatusTransferItems
+
+  for (int j = 0; j < (int) sz; j++)
+    {
+      EpcX2Sap::ErabsSubjectToStatusTransferItem item = m_erabsSubjectToStatusTransferList [j];
+
+      i.WriteHtonU16 (item.erabId);
+
+      uint16_t bitsetSize = EpcX2Sap::m_maxPdcpSn / 64;
+      for (int k = 0; k < bitsetSize; k++)
+        {
+          uint64_t statusValue = 0;
+          for (int m = 0; m < 64; m++)
+            {
+              statusValue |= item.receiveStatusOfUlPdcpSdus[64 * k + m] << m;
+            }
+          i.WriteHtonU64 (statusValue);
+        }
+
+      i.WriteHtonU16 (item.ulPdcpSn);
+      i.WriteHtonU32 (item.ulHfn);
+      i.WriteHtonU16 (item.dlPdcpSn);
+      i.WriteHtonU32 (item.dlHfn);
+    }
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+
+  m_oldEnbUeX2apId = i.ReadNtohU16 ();
+  m_newEnbUeX2apId = i.ReadNtohU16 ();
+  int sz = i.ReadNtohU16 ();
+
+  m_numberOfIes = 3;
+  m_headerLength = 6 + sz * (14 + (EpcX2Sap::m_maxPdcpSn / 64));
+
+  for (int j = 0; j < sz; j++)
+    {
+      EpcX2Sap::ErabsSubjectToStatusTransferItem ErabItem;
+      ErabItem.erabId = i.ReadNtohU16 ();
+
+      uint16_t bitsetSize = EpcX2Sap::m_maxPdcpSn / 64;
+      for (int k = 0; k < bitsetSize; k++)
+        {
+          uint64_t statusValue = i.ReadNtohU64 ();
+          for (int m = 0; m < 64; m++)
+            {
+              ErabItem.receiveStatusOfUlPdcpSdus[64 * k + m] = (statusValue >> m) & 1;
+            }
+        }
+
+      ErabItem.ulPdcpSn = i.ReadNtohU16 ();
+      ErabItem.ulHfn    = i.ReadNtohU32 ();
+      ErabItem.dlPdcpSn = i.ReadNtohU16 ();
+      ErabItem.dlHfn    = i.ReadNtohU32 ();
+
+      m_erabsSubjectToStatusTransferList.push_back (ErabItem);
+    }
+
+  return GetSerializedSize ();
+}
+
+void
+EpcX2SnStatusTransferHeader::Print (std::ostream &os) const
+{
+  os << "OldEnbUeX2apId = " << m_oldEnbUeX2apId;
+  os << " NewEnbUeX2apId = " << m_newEnbUeX2apId;
+  os << " ErabsSubjectToStatusTransferList size = " << m_erabsSubjectToStatusTransferList.size ();
+
+  std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem>::size_type sz = m_erabsSubjectToStatusTransferList.size ();
+  if (sz > 0)
+    {
+      os << " [";
+    }
+  for (int j = 0; j < (int) sz; j++)
+    {
+      os << m_erabsSubjectToStatusTransferList[j].erabId;
+      if (j < (int) sz - 1)
+        {
+          os << ", ";
+        }
+      else
+        {
+          os << "]";
+        }
+    }
+}
+
+uint16_t
+EpcX2SnStatusTransferHeader::GetOldEnbUeX2apId () const
+{
+  return m_oldEnbUeX2apId;
+}
+
+void
+EpcX2SnStatusTransferHeader::SetOldEnbUeX2apId (uint16_t x2apId)
+{
+  m_oldEnbUeX2apId = x2apId;
+}
+
+uint16_t
+EpcX2SnStatusTransferHeader::GetNewEnbUeX2apId () const
+{
+  return m_newEnbUeX2apId;
+}
+
+void
+EpcX2SnStatusTransferHeader::SetNewEnbUeX2apId (uint16_t x2apId)
+{
+  m_newEnbUeX2apId = x2apId;
+}
+
+std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem>
+EpcX2SnStatusTransferHeader::GetErabsSubjectToStatusTransferList () const
+{
+  return m_erabsSubjectToStatusTransferList;
+}
+
+void
+EpcX2SnStatusTransferHeader::SetErabsSubjectToStatusTransferList (std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> erabs)
+{
+  m_headerLength += erabs.size () * (14 + (EpcX2Sap::m_maxPdcpSn / 8));
+  m_erabsSubjectToStatusTransferList = erabs;
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::GetLengthOfIes () const
+{
+  return m_headerLength;
+}
+
+uint32_t
+EpcX2SnStatusTransferHeader::GetNumberOfIes () const
+{
+  return m_numberOfIes;
+}
+
+/////////////////////////////////////////////////////////////////////
+
 NS_OBJECT_ENSURE_REGISTERED (EpcX2UeContextReleaseHeader);
 
 EpcX2UeContextReleaseHeader::EpcX2UeContextReleaseHeader ()
@@ -1119,8 +1311,8 @@
 EpcX2ResourceStatusUpdateHeader::EpcX2ResourceStatusUpdateHeader ()
   : m_numberOfIes (3),
     m_headerLength (6),
-    m_enb1MeasurementId (0),
-    m_enb2MeasurementId (0)
+    m_enb1MeasurementId (0xfffa),
+    m_enb2MeasurementId (0xfffa)
 {
   m_cellMeasurementResultList.clear ();
 }
@@ -1129,8 +1321,8 @@
 {
   m_numberOfIes = 0;
   m_headerLength = 0;
-  m_enb1MeasurementId = 0;
-  m_enb2MeasurementId = 0;
+  m_enb1MeasurementId = 0xfffb;
+  m_enb2MeasurementId = 0xfffb;
   m_cellMeasurementResultList.clear ();
 }
 
--- a/src/lte/model/epc-x2-header.h	Wed Dec 05 13:43:21 2012 +0100
+++ b/src/lte/model/epc-x2-header.h	Wed Dec 05 13:52:42 2012 +0100
@@ -57,6 +57,7 @@
   enum ProcedureCode_t {
     HandoverPreparation     = 0,
     LoadIndication          = 2,
+    SnStatusTransfer        = 4,
     UeContextRelease        = 5,
     ResourceStatusReporting = 10
   };
@@ -206,6 +207,42 @@
 };
 
 
+class EpcX2SnStatusTransferHeader : public Header
+{
+public:
+  EpcX2SnStatusTransferHeader ();
+  virtual ~EpcX2SnStatusTransferHeader ();
+
+  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);
+
+  std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> GetErabsSubjectToStatusTransferList () const;
+  void SetErabsSubjectToStatusTransferList (std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> erabs);
+
+  uint32_t GetLengthOfIes () const;
+  uint32_t GetNumberOfIes () const;
+
+private:
+  uint32_t          m_numberOfIes;
+  uint32_t          m_headerLength;
+
+  uint16_t          m_oldEnbUeX2apId;
+  uint16_t          m_newEnbUeX2apId;
+  std::vector <EpcX2Sap::ErabsSubjectToStatusTransferItem> m_erabsSubjectToStatusTransferList;
+};
+
+
 class EpcX2UeContextReleaseHeader : public Header
 {
 public:
--- a/src/lte/model/epc-x2-sap.h	Wed Dec 05 13:43:21 2012 +0100
+++ b/src/lte/model/epc-x2-sap.h	Wed Dec 05 13:52:42 2012 +0100
@@ -25,6 +25,8 @@
 #include "ns3/eps-bearer.h"
 #include "ns3/ipv4-address.h"
 
+#include <bitset>
+
 namespace ns3 {
 
 
@@ -89,6 +91,22 @@
   };
 
   /**
+   * E-RABs subject to status transfer item as
+   * it is used in the SN STATUS TRANSFER message.
+   * See section 9.1.1.4 for further info about the parameters
+   */
+  static const uint16_t m_maxPdcpSn = 4096;
+  struct ErabsSubjectToStatusTransferItem
+  {
+    uint16_t            erabId;
+    std::bitset<m_maxPdcpSn> receiveStatusOfUlPdcpSdus;
+    uint16_t            ulPdcpSn;
+    uint32_t            ulHfn;
+    uint16_t            dlPdcpSn;
+    uint32_t            dlHfn;
+  };
+
+  /**
    * UL Interference OverloadIndication as
    * it is used in the LOAD INFORMATION message.
    * See section 9.2.17 for further info about the values
@@ -248,6 +266,20 @@
   };
 
   /**
+   * \brief Parameters of the SN STATUS TRANSFER message.
+   *
+   * See section 9.1.1.4 for further info about the parameters
+   */
+  struct SnStatusTransferParams
+  {
+    uint16_t            oldEnbUeX2apId;
+    uint16_t            newEnbUeX2apId;
+    uint16_t            sourceCellId;
+    uint16_t            targetCellId;
+    std::vector <ErabsSubjectToStatusTransferItem> erabsSubjectToStatusTransferList;
+  };
+
+  /**
    * \brief Parameters of the UE CONTEXT RELEASE message.
    *
    * See section 9.1.1.5 for further info about the parameters
@@ -257,6 +289,7 @@
     uint16_t            oldEnbUeX2apId;
     uint16_t            newEnbUeX2apId;
     uint16_t            sourceCellId;
+    uint16_t            targetCellId;
   };
 
   /**
@@ -305,6 +338,8 @@
 
   virtual void SendHandoverPreparationFailure (HandoverPreparationFailureParams params) = 0;
 
+  virtual void SendSnStatusTransfer (SnStatusTransferParams params) = 0;
+
   virtual void SendUeContextRelease (UeContextReleaseParams params) = 0;
 
   virtual void SendLoadInformation (LoadInformationParams params) = 0;
@@ -332,6 +367,8 @@
 
   virtual void RecvHandoverPreparationFailure (HandoverPreparationFailureParams params) = 0;
 
+  virtual void RecvSnStatusTransfer (SnStatusTransferParams params) = 0;
+
   virtual void RecvUeContextRelease (UeContextReleaseParams params) = 0;
 
   virtual void RecvLoadInformation (LoadInformationParams params) = 0;
@@ -357,6 +394,8 @@
 
   virtual void SendHandoverPreparationFailure (HandoverPreparationFailureParams params);
 
+  virtual void SendSnStatusTransfer (SnStatusTransferParams params);
+
   virtual void SendUeContextRelease (UeContextReleaseParams params);
 
   virtual void SendLoadInformation (LoadInformationParams params);
@@ -402,6 +441,13 @@
 
 template <class C>
 void
+EpcX2SpecificEpcX2SapProvider<C>::SendSnStatusTransfer (SnStatusTransferParams params)
+{
+  m_x2->DoSendSnStatusTransfer (params);
+}
+
+template <class C>
+void
 EpcX2SpecificEpcX2SapProvider<C>::SendUeContextRelease (UeContextReleaseParams params)
 {
   m_x2->DoSendUeContextRelease (params);
@@ -439,6 +485,8 @@
 
   virtual void RecvHandoverPreparationFailure (HandoverPreparationFailureParams params);
 
+  virtual void RecvSnStatusTransfer (SnStatusTransferParams params);
+
   virtual void RecvUeContextRelease (UeContextReleaseParams params);
 
   virtual void RecvLoadInformation (LoadInformationParams params);
@@ -484,6 +532,13 @@
 
 template <class C>
 void
+EpcX2SpecificEpcX2SapUser<C>::RecvSnStatusTransfer (SnStatusTransferParams params)
+{
+  m_rrc->DoRecvSnStatusTransfer (params);
+}
+
+template <class C>
+void
 EpcX2SpecificEpcX2SapUser<C>::RecvUeContextRelease (UeContextReleaseParams params)
 {
   m_rrc->DoRecvUeContextRelease (params);
--- a/src/lte/model/epc-x2.cc	Wed Dec 05 13:43:21 2012 +0100
+++ b/src/lte/model/epc-x2.cc	Wed Dec 05 13:52:42 2012 +0100
@@ -164,6 +164,10 @@
   Ptr<Packet> packet = socket->Recv ();
   NS_LOG_LOGIC ("packetLen = " << packet->GetSize ());
 
+  NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
+                 "Missing infos of local and remote CellId");
+  Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
+
   EpcX2Header x2Header;
   packet->RemoveHeader (x2Header);
 
@@ -172,9 +176,6 @@
   uint8_t messageType = x2Header.GetMessageType ();
   uint8_t procedureCode = x2Header.GetProcedureCode ();
 
-  NS_LOG_LOGIC ("messageType = " << (uint32_t)messageType);
-  NS_LOG_LOGIC ("procedureCode = " << (uint32_t)procedureCode);
-
   if (procedureCode == EpcX2Header::HandoverPreparation)
     {
       if (messageType == EpcX2Header::InitiatingMessage)
@@ -186,10 +187,6 @@
 
           NS_LOG_INFO ("X2 HandoverRequest header: " << x2HoReqHeader);
 
-          NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
-                         "Missing infos of local and remote CellId");
-          Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
-
           EpcX2SapUser::HandoverRequestParams params;
           params.oldEnbUeX2apId = x2HoReqHeader.GetOldEnbUeX2apId ();
           params.cause          = x2HoReqHeader.GetCause ();
@@ -218,9 +215,7 @@
           EpcX2HandoverRequestAckHeader x2HoReqAckHeader;
           packet->RemoveHeader (x2HoReqAckHeader);
 
-          NS_ASSERT_MSG (m_x2InterfaceCellIds.find (socket) != m_x2InterfaceCellIds.end (),
-                         "Missing infos of local and remote CellId");
-          Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
+          NS_LOG_INFO ("X2 HandoverRequestAck header: " << x2HoReqAckHeader);
 
           EpcX2SapUser::HandoverRequestAckParams params;          
           params.oldEnbUeX2apId = x2HoReqAckHeader.GetOldEnbUeX2apId ();
@@ -245,9 +240,7 @@
           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];
+          NS_LOG_INFO ("X2 HandoverPreparationFailure header: " << x2HoPrepFailHeader);
 
           EpcX2SapUser::HandoverPreparationFailureParams params;          
           params.oldEnbUeX2apId = x2HoPrepFailHeader.GetOldEnbUeX2apId ();
@@ -284,6 +277,33 @@
           m_x2SapUser->RecvLoadInformation (params);
         }
     }
+  else if (procedureCode == EpcX2Header::SnStatusTransfer)
+    {
+      if (messageType == EpcX2Header::InitiatingMessage)
+        {
+          NS_LOG_LOGIC ("Recv X2 message: SN STATUS TRANSFER");
+
+            EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
+            packet->RemoveHeader (x2SnStatusXferHeader);
+
+            NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
+
+            EpcX2SapUser::SnStatusTransferParams params;
+            params.oldEnbUeX2apId = x2SnStatusXferHeader.GetOldEnbUeX2apId ();
+            params.newEnbUeX2apId = x2SnStatusXferHeader.GetNewEnbUeX2apId ();
+            params.sourceCellId   = cellsInfo->m_remoteCellId;
+            params.targetCellId   = cellsInfo->m_localCellId;
+            params.erabsSubjectToStatusTransferList = x2SnStatusXferHeader.GetErabsSubjectToStatusTransferList ();
+
+            NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+            NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
+            NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
+            NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
+            NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
+
+            m_x2SapUser->RecvSnStatusTransfer (params);
+        }
+    }
   else if (procedureCode == EpcX2Header::UeContextRelease)
     {
       if (messageType == EpcX2Header::InitiatingMessage)
@@ -486,6 +506,54 @@
 
 
 void
+EpcX2::DoSendSnStatusTransfer (EpcX2SapProvider::SnStatusTransferParams params)
+{
+  NS_LOG_FUNCTION (this);
+
+  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
+  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
+  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
+  NS_LOG_LOGIC ("erabsList size = " << params.erabsSubjectToStatusTransferList.size ());
+
+  NS_ASSERT_MSG (m_x2InterfaceSockets.find (params.targetCellId) != m_x2InterfaceSockets.end (),
+                 "Socket infos not defined for targetCellId = " << params.targetCellId);
+
+  Ptr<Socket> localSocket = m_x2InterfaceSockets [params.targetCellId]->m_localSocket;
+  Ipv4Address remoteIpAddr = m_x2InterfaceSockets [params.targetCellId]->m_remoteIpAddr;
+
+  NS_LOG_LOGIC ("localSocket = " << localSocket);
+  NS_LOG_LOGIC ("remoteIpAddr = " << remoteIpAddr);
+
+  NS_LOG_INFO ("Send X2 message: SN STATUS TRANSFER");
+
+  // Build the X2 message
+  EpcX2SnStatusTransferHeader x2SnStatusXferHeader;
+  x2SnStatusXferHeader.SetOldEnbUeX2apId (params.oldEnbUeX2apId);
+  x2SnStatusXferHeader.SetNewEnbUeX2apId (params.newEnbUeX2apId);
+  x2SnStatusXferHeader.SetErabsSubjectToStatusTransferList (params.erabsSubjectToStatusTransferList);
+
+  EpcX2Header x2Header;
+  x2Header.SetMessageType (EpcX2Header::InitiatingMessage);
+  x2Header.SetProcedureCode (EpcX2Header::SnStatusTransfer);
+  x2Header.SetLengthOfIes (x2SnStatusXferHeader.GetLengthOfIes ());
+  x2Header.SetNumberOfIes (x2SnStatusXferHeader.GetNumberOfIes ());
+
+  NS_LOG_INFO ("X2 header: " << x2Header);
+  NS_LOG_INFO ("X2 SnStatusTransfer header: " << x2SnStatusXferHeader);
+
+  // Build the X2 packet
+  Ptr<Packet> packet = Create <Packet> ();
+  packet->AddHeader (x2SnStatusXferHeader);
+  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	Wed Dec 05 13:43:21 2012 +0100
+++ b/src/lte/model/epc-x2.h	Wed Dec 05 13:52:42 2012 +0100
@@ -116,6 +116,7 @@
   virtual void DoSendHandoverRequest (EpcX2SapProvider::HandoverRequestParams params);
   virtual void DoSendHandoverRequestAck (EpcX2SapProvider::HandoverRequestAckParams params);
   virtual void DoSendHandoverPreparationFailure (EpcX2SapProvider::HandoverPreparationFailureParams params);
+  virtual void DoSendSnStatusTransfer (EpcX2SapProvider::SnStatusTransferParams 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	Wed Dec 05 13:43:21 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.cc	Wed Dec 05 13:52:42 2012 +0100
@@ -1359,6 +1359,20 @@
 }
 
 void
+LteEnbRrc::DoRecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params)
+{
+  NS_LOG_FUNCTION (this);
+
+  NS_LOG_LOGIC ("Recv X2 message: SN STATUS TRANSFER");
+
+  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
+  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
+  NS_LOG_LOGIC ("erabsSubjectToStatusTransferList size = " << params.erabsSubjectToStatusTransferList.size ());
+
+  NS_ASSERT ("Processing of SN STATUS TRANSFER X2 message IS NOT IMPLEMENTED");
+}
+
+void
 LteEnbRrc::DoRecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params)
 {
   NS_LOG_FUNCTION (this);
--- a/src/lte/model/lte-enb-rrc.h	Wed Dec 05 13:43:21 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.h	Wed Dec 05 13:52:42 2012 +0100
@@ -576,6 +576,7 @@
   void DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params);
   void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
   void DoRecvHandoverPreparationFailure (EpcX2SapUser::HandoverPreparationFailureParams params);
+  void DoRecvSnStatusTransfer (EpcX2SapUser::SnStatusTransferParams params);
   void DoRecvUeContextRelease (EpcX2SapUser::UeContextReleaseParams params);
   void DoRecvLoadInformation (EpcX2SapUser::LoadInformationParams params);
   void DoRecvResourceStatusUpdate (EpcX2SapUser::ResourceStatusUpdateParams params);