LteEnbRrc forwarding data over X2-U during handover
authorNicola Baldo <nbaldo@cttc.es>
Wed, 19 Dec 2012 20:27:46 +0100
changeset 9599 fc4c980050f2
parent 9598 5bc54db84485
child 9600 6997e80b2ba9
child 9603 a98156dcde1c
LteEnbRrc forwarding data over X2-U during handover
src/lte/model/lte-enb-rrc.cc
src/lte/model/lte-enb-rrc.h
--- a/src/lte/model/lte-enb-rrc.cc	Wed Dec 19 21:21:35 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.cc	Wed Dec 19 20:27:46 2012 +0100
@@ -273,6 +273,13 @@
     {
       m_rrc->m_s1SapProvider->UeContextRelease (m_rnti);
     }
+  // delete eventual X2-U TEIDs
+  for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
+       it != m_drbMap.end ();
+       ++it)
+    {
+      m_rrc->m_x2uTeidInfoMap.erase (it->second->m_gtpTeid);
+    }    
 }
 
 TypeId UeManager::GetTypeId (void)
@@ -320,6 +327,17 @@
   drbInfo->m_gtpTeid = gtpTeid;
   drbInfo->m_transportLayerAddress = transportLayerAddress;
 
+  if (m_state == HANDOVER_JOINING)
+    {
+      // setup TEIDs for receiving data eventually forwarded over X2-U 
+      LteEnbRrc::X2uTeidInfo x2uTeidInfo;
+      x2uTeidInfo.rnti = m_rnti;
+      x2uTeidInfo.drbid = drbid;
+      std::pair<std::map<uint32_t, LteEnbRrc::X2uTeidInfo>::iterator, bool>
+        ret = m_rrc->m_x2uTeidInfoMap.insert (std::pair<uint32_t, LteEnbRrc::X2uTeidInfo> (gtpTeid, x2uTeidInfo));
+      NS_ASSERT_MSG (ret.second == true, "overwriting a pre-existing entry in m_x2uTeidInfoMap");
+    }
+
   TypeId rlcTypeId = m_rrc->GetRlcType (bearer);
 
   ObjectFactory rlcObjectFactory;
@@ -421,6 +439,10 @@
   uint8_t lcid = Drbid2Lcid (drbid);
   std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
   NS_ASSERT_MSG (it != m_drbMap.end (), "request to remove radio bearer with unknown drbid " << drbid);
+
+  // first delete eventual X2-U TEIDs
+  m_rrc->m_x2uTeidInfoMap.erase (it->second->m_gtpTeid);
+
   m_drbMap.erase (it);
   m_rrc->m_cmacSapProvider->ReleaseLc (m_rnti, lcid);
 
@@ -580,13 +602,49 @@
 UeManager::SendData (uint8_t bid, Ptr<Packet> p)
 {
   NS_LOG_FUNCTION (this << p << (uint16_t) bid);
-  LtePdcpSapProvider::TransmitPdcpSduParameters params;
-  params.pdcpSdu = p;
-  params.rnti = m_rnti;
-  params.lcid = Bid2Lcid (bid);
-  uint8_t drbid = Bid2Drbid (bid);
-  LtePdcpSapProvider* pdcpSapProvider = GetDataRadioBearerInfo (drbid)->m_pdcp->GetLtePdcpSapProvider ();
-  pdcpSapProvider->TransmitPdcpSdu (params);
+   switch (m_state)
+    {
+    case INITIAL_RANDOM_ACCESS:
+    case CONNECTION_SETUP:
+      NS_LOG_WARN ("not connected, discarding packet");
+      return;
+      break;      
+      
+    case CONNECTED_NORMALLY:      
+    case CONNECTION_RECONFIGURATION:
+    case CONNECTION_REESTABLISHMENT:
+    case HANDOVER_PREPARATION:
+    case HANDOVER_JOINING:
+    case HANDOVER_PATH_SWITCH:
+      {
+        NS_LOG_LOGIC ("queueing data on PDCP for transmission over the air");
+        LtePdcpSapProvider::TransmitPdcpSduParameters params;
+        params.pdcpSdu = p;
+        params.rnti = m_rnti;
+        params.lcid = Bid2Lcid (bid);
+        uint8_t drbid = Bid2Drbid (bid);
+        LtePdcpSapProvider* pdcpSapProvider = GetDataRadioBearerInfo (drbid)->m_pdcp->GetLtePdcpSapProvider ();
+        pdcpSapProvider->TransmitPdcpSdu (params);
+      }
+      break;
+      
+    case HANDOVER_LEAVING:
+      {
+        NS_LOG_LOGIC ("forwarding data to target eNB over X2-U");
+        uint8_t drbid = Bid2Drbid (bid);        
+        EpcX2Sap::UeDataParams params;
+        params.sourceCellId = m_rrc->m_cellId;
+        params.targetCellId = m_targetCellId;
+        params.gtpTeid = GetDataRadioBearerInfo (drbid)->m_gtpTeid;
+        params.ueData = p;
+        m_rrc->m_x2SapProvider->SendUeData (params);
+      }      
+      break;
+      
+    default:
+      NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
+      break;      
+    }
 }
 
 std::vector<EpcX2Sap::ErabToBeSetupItem>   
@@ -1577,7 +1635,16 @@
   NS_LOG_LOGIC ("ueData = " << params.ueData);
   NS_LOG_LOGIC ("ueData size = " << params.ueData->GetSize ());
 
-  NS_ASSERT ("Processing of UE DATA FORWARDING through X2 interface IS NOT IMPLEMENTED");
+  std::map<uint32_t, X2uTeidInfo>::iterator 
+    teidInfoIt = m_x2uTeidInfoMap.find (params.gtpTeid);
+  if (teidInfoIt != m_x2uTeidInfoMap.end ())    
+    {
+      GetUeManager (teidInfoIt->second.rnti)->SendData (teidInfoIt->second.drbid, params.ueData);
+    }
+  else
+    {
+      NS_FATAL_ERROR ("X2-U data received but no X2uTeidInfo found");
+    }
 }
 
 
--- a/src/lte/model/lte-enb-rrc.h	Wed Dec 19 21:21:35 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.h	Wed Dec 19 20:27:46 2012 +0100
@@ -204,7 +204,6 @@
    */
   std::vector<EpcX2Sap::ErabToBeSetupItem> GetErabList ();
 
-
   /** 
    * send the UE CONTEXT RELEASE X2 message to the source eNB, thus
    * successfully terminating an X2 handover procedure 
@@ -742,6 +741,15 @@
   uint16_t m_lastAllocatedRnti;
 
   std::map<uint16_t, Ptr<UeManager> > m_ueMap;  
+
+  struct X2uTeidInfo
+  {
+    uint16_t rnti;
+    uint8_t drbid;
+  };
+    
+  //       TEID      RNTI, DRBID
+  std::map<uint32_t, X2uTeidInfo> m_x2uTeidInfoMap; 
   
   uint8_t m_defaultTransmissionMode;