added S1 path switch + S11 modify bearer for X2 handover
authorNicola Baldo <nbaldo@cttc.es>
Thu, 29 Nov 2012 12:00:06 +0100
changeset 9439 5107601b7a75
parent 9438 05361705484a
child 9440 eb053bae286c
added S1 path switch + S11 modify bearer for X2 handover
src/lte/helper/epc-helper.cc
src/lte/helper/lte-helper.cc
src/lte/helper/lte-helper.h
src/lte/model/epc-enb-application.cc
src/lte/model/epc-enb-application.h
src/lte/model/epc-enb-s1-sap.h
src/lte/model/epc-mme.cc
src/lte/model/epc-mme.h
src/lte/model/epc-s11-sap.h
src/lte/model/epc-s1ap-sap.h
src/lte/model/epc-sgw-pgw-application.cc
src/lte/model/epc-sgw-pgw-application.h
src/lte/model/lte-enb-net-device.cc
src/lte/model/lte-enb-net-device.h
src/lte/model/lte-enb-rrc.cc
src/lte/model/lte-enb-rrc.h
src/lte/model/lte-ue-net-device.cc
src/lte/model/lte-ue-net-device.h
src/lte/model/lte-ue-phy.cc
src/lte/test/lte-test-entities.cc
src/lte/test/lte-test-entities.h
--- a/src/lte/helper/epc-helper.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/helper/epc-helper.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -201,7 +201,7 @@
   
 
   NS_LOG_INFO ("create EpcEnbApplication");
-  Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, sgwAddress, cellId);
+  Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, enbAddress, sgwAddress, cellId);
   enb->AddApplication (enbApp);
   NS_ASSERT (enb->GetNApplications () == 1);
   NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
--- a/src/lte/helper/lte-helper.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/helper/lte-helper.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -61,6 +61,8 @@
 NS_OBJECT_ENSURE_REGISTERED (LteHelper);
 
 LteHelper::LteHelper (void)
+  :   m_imsiCounter (0),
+      m_cellIdCounter (0)
 {
   NS_LOG_FUNCTION (this);
   m_enbNetDeviceFactory.SetTypeId (LteEnbNetDevice::GetTypeId ());
@@ -374,8 +376,12 @@
   phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
   rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
  
+  NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
+  uint16_t cellId = ++m_cellIdCounter;
+
   Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
   dev->SetNode (n);
+  dev->SetAttribute ("CellId", UintegerValue (cellId)); 
   dev->SetAttribute ("LteEnbPhy", PointerValue (phy));
   dev->SetAttribute ("LteEnbMac", PointerValue (mac));
   dev->SetAttribute ("FfMacScheduler", PointerValue (sched));
@@ -497,7 +503,9 @@
   phy->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser ());
   rrc->SetLteUeCphySapProvider (phy->GetLteUeCphySapProvider ());
 
-  Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc, nas);
+  NS_ABORT_MSG_IF (m_imsiCounter >= 0xFFFFFFFF, "max num UEs exceeded");  
+  uint64_t imsi = ++m_imsiCounter;
+  Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc, nas, imsi);
   phy->SetDevice (dev);
   dlPhy->SetDevice (dev);
   ulPhy->SetDevice (dev);
--- a/src/lte/helper/lte-helper.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/helper/lte-helper.h	Thu Nov 29 12:00:06 2012 +0100
@@ -406,6 +406,10 @@
 
   Ptr<EpcHelper> m_epcHelper;
 
+  uint64_t m_imsiCounter;
+  uint16_t m_cellIdCounter;
+
+
 };
 
 
--- a/src/lte/model/epc-enb-application.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-enb-application.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -78,16 +78,17 @@
 }
 
 
-EpcEnbApplication::EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address sgwAddress, uint16_t cellId)
+EpcEnbApplication::EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId)
   : m_lteSocket (lteSocket),
     m_s1uSocket (s1uSocket),    
-    m_sgwAddress (sgwAddress),
+    m_enbS1uAddress (enbS1uAddress),
+    m_sgwS1uAddress (sgwS1uAddress),
     m_gtpuUdpPort (2152), // fixed by the standard
     m_s1SapUser (0),
     m_s1apSapMme (0),
     m_cellId (cellId)
 {
-  NS_LOG_FUNCTION (this << lteSocket << s1uSocket << sgwAddress);
+  NS_LOG_FUNCTION (this << lteSocket << s1uSocket << sgwS1uAddress);
   m_s1uSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromS1uSocket, this));
   m_lteSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromLteSocket, this));
   m_s1SapProvider = new MemberEpcEnbS1SapProvider<EpcEnbApplication> (this);
@@ -136,6 +137,41 @@
   m_s1apSapMme->InitialUeMessage (imsi, rnti, imsi, m_cellId);
 }
 
+void 
+EpcEnbApplication::DoPathSwitchRequest (EpcEnbS1SapProvider::PathSwitchRequestParameters params)
+{
+  NS_LOG_FUNCTION (this);
+  uint16_t enbUeS1Id = params.rnti;  
+  uint64_t mmeUeS1Id = params.mmeUeS1Id;
+  uint64_t imsi = mmeUeS1Id;
+  // side effect: create entry if not exist
+  m_imsiRntiMap[imsi] = params.rnti;
+
+  uint16_t gci = params.cellId;
+  std::list<EpcS1apSapMme::ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList;
+  for (std::list<EpcEnbS1SapProvider::BearerToBeSwitched>::iterator bit = params.bearersToBeSwitched.begin ();
+       bit != params.bearersToBeSwitched.end ();
+       ++bit)
+    {
+      EpsFlowId_t flowId;
+      flowId.m_rnti = params.rnti;
+      flowId.m_bid = bit->epsBearerId;
+      uint32_t teid = bit->teid;
+      
+      EpsFlowId_t rbid (params.rnti, bit->epsBearerId);
+      // side effect: create entries if not exist
+      m_rbidTeidMap[rbid] = teid;
+      m_teidRbidMap[teid] = rbid;
+
+      EpcS1apSapMme::ErabSwitchedInDownlinkItem erab;
+      erab.erabId = bit->epsBearerId;
+      erab.enbTransportLayerAddress = m_enbS1uAddress;
+      erab.enbTeid = bit->teid;
+
+      erabToBeSwitchedInDownlinkList.push_back (erab);
+    }
+  m_s1apSapMme->PathSwitchRequest (enbUeS1Id, mmeUeS1Id, gci, erabToBeSwitchedInDownlinkList);
+}
 
 void 
 EpcEnbApplication::DoInitialContextSetupRequest (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapEnb::ErabToBeSetupItem> erabToBeSetupList)
@@ -172,7 +208,14 @@
 EpcEnbApplication::DoPathSwitchRequestAcknowledge (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list<EpcS1apSapEnb::ErabSwitchedInUplinkItem> erabToBeSwitchedInUplinkList)
 {
   NS_LOG_FUNCTION (this);
-  NS_FATAL_ERROR ("not implemented");
+
+  uint64_t imsi = mmeUeS1Id;
+  std::map<uint64_t, uint16_t>::iterator imsiIt = m_imsiRntiMap.find (imsi);
+  NS_ASSERT_MSG (imsiIt != m_imsiRntiMap.end (), "unknown IMSI");
+  uint16_t rnti = imsiIt->second;
+  EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params;
+  params.rnti = rnti;
+  m_s1SapUser->PathSwitchRequestAcknowledge (params);
 }
 
 void 
@@ -240,7 +283,7 @@
   gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);  
   packet->AddHeader (gtpu);
   uint32_t flags = 0;
-  m_s1uSocket->SendTo (packet, flags, InetSocketAddress(m_sgwAddress, m_gtpuUdpPort));
+  m_s1uSocket->SendTo (packet, flags, InetSocketAddress(m_sgwS1uAddress, m_gtpuUdpPort));
 }
 
 
--- a/src/lte/model/epc-enb-application.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-enb-application.h	Thu Nov 29 12:00:06 2012 +0100
@@ -69,10 +69,11 @@
    * \param lteSocket the socket to be used to send/receive packets to/from the LTE radio interface
    * \param s1uSocket the socket to be used to send/receive packets
    * to/from the S1-U interface connected with the SGW 
-   * \param sgwAddress the IPv4 address at which this eNB will be able to reach its SGW
+   * \param enbS1uAddress the IPv4 address of the S1-U interface of this eNB
+   * \param sgwS1uAddress the IPv4 address at which this eNB will be able to reach its SGW for S1-U communications
    * \param cellId the identifier of the enb
    */
-  EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address sgwAddress, uint16_t cellId);
+  EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId);
 
   /**
    * Destructor
@@ -141,6 +142,7 @@
 
   // ENB S1 SAP provider methods
   void DoInitialUeMessage (uint64_t imsi, uint16_t rnti);
+  void DoPathSwitchRequest (EpcEnbS1SapProvider::PathSwitchRequestParameters params);
 
   // S1-AP SAP ENB methods
   void DoInitialContextSetupRequest (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapEnb::ErabToBeSetupItem> erabToBeSetupList);
@@ -185,9 +187,14 @@
   Ptr<Socket> m_s1uSocket;
 
   /**
+   * address of the eNB for S1-U communications
+   */
+  Ipv4Address m_enbS1uAddress;
+
+  /**
    * address of the SGW which terminates all S1-U tunnels
    */
-  Ipv4Address m_sgwAddress;
+  Ipv4Address m_sgwS1uAddress;
 
   /**
    * map telling for each EpsBearer (RNTI,BID) the corresponding  S1-U TEID
--- a/src/lte/model/epc-enb-s1-sap.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-enb-s1-sap.h	Thu Nov 29 12:00:06 2012 +0100
@@ -21,6 +21,7 @@
 #ifndef EPC_ENB_S1_SAP_H
 #define EPC_ENB_S1_SAP_H
 
+#include <list>
 #include <stdint.h>
 #include <ns3/eps-bearer.h>
 #include <ns3/ipv4-address.h>
@@ -38,20 +39,7 @@
 class EpcEnbS1SapProvider
 {
 public:
-  virtual ~EpcEnbS1SapProvider ();
-  
-  /**
-   * Parameters passed to S1BearerSetupRequest ()
-   * 
-   */
-  struct S1BearerSetupRequestParameters
-  {
-    uint16_t rnti; /**< the RNTI corresponding to the IMSI for which
-                      the radio bearer activation was requested */
-    uint8_t bid; /**< the EPS Bearer ID of the bearer to be created*/
-
-    uint32_t gtpTeid; /**<  S1-bearer GTP tunnel endpoint identifier, see 36.423 9.2.1  */
-  };
+  virtual ~EpcEnbS1SapProvider ();  
 
   /** 
    * 
@@ -60,6 +48,24 @@
    * \param rnti 
    */
   virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti) = 0;
+
+
+  struct BearerToBeSwitched
+  {
+    uint8_t epsBearerId;
+    uint32_t teid;
+  };
+  
+  struct PathSwitchRequestParameters
+  {
+    uint16_t rnti;
+    uint16_t cellId;
+    uint32_t mmeUeS1Id;
+    std::list<BearerToBeSwitched> bearersToBeSwitched;
+  };
+
+  virtual void PathSwitchRequest (PathSwitchRequestParameters params) = 0;
+    
 };
   
 
@@ -96,6 +102,14 @@
    * 
    */
   virtual void DataRadioBearerSetupRequest (DataRadioBearerSetupRequestParameters params) = 0;
+
+  
+  struct PathSwitchRequestAcknowledgeParameters
+  {
+    uint16_t rnti;
+  };
+
+  virtual void PathSwitchRequestAcknowledge (PathSwitchRequestAcknowledgeParameters params) = 0;
   
 };
   
@@ -115,6 +129,8 @@
 
   // inherited from EpcEnbS1SapProvider
   virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti);
+  virtual void PathSwitchRequest (PathSwitchRequestParameters params);
+  
 
 private:
   MemberEpcEnbS1SapProvider ();
@@ -139,6 +155,13 @@
   m_owner->DoInitialUeMessage (imsi, rnti);
 }
 
+
+template <class C>
+void MemberEpcEnbS1SapProvider<C>::PathSwitchRequest (PathSwitchRequestParameters params)
+{
+  m_owner->DoPathSwitchRequest (params);
+}
+
 /**
  * Template for the implementation of the EpcEnbS1SapUser as a member
  * of an owner class of type C to which all methods are forwarded
@@ -152,6 +175,7 @@
 
   // inherited from EpcEnbS1SapUser
   virtual void DataRadioBearerSetupRequest (DataRadioBearerSetupRequestParameters params);
+  virtual void PathSwitchRequestAcknowledge (PathSwitchRequestAcknowledgeParameters params);
 
 private:
   MemberEpcEnbS1SapUser ();
@@ -175,6 +199,11 @@
   m_owner->DoDataRadioBearerSetupRequest (params);
 }
 
+template <class C>
+void MemberEpcEnbS1SapUser<C>::PathSwitchRequestAcknowledge (PathSwitchRequestAcknowledgeParameters params)
+{
+  m_owner->DoPathSwitchRequestAcknowledge (params);
+}
 
 } // namespace ns3
 
--- a/src/lte/model/epc-mme.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-mme.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -131,20 +131,20 @@
   std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
   NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
   it->second->cellId = gci;
-  std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup;
+  EpcS11SapSgw::CreateSessionRequestMessage msg;
+  msg.imsi = imsi;
+  msg. uli.gci = gci;
   for (std::list<BearerInfo>::iterator bit = it->second->bearersToBeActivated.begin ();
        bit != it->second->bearersToBeActivated.end ();
        ++bit)
     {
-      EpcS11SapSgw::BearerContext bearerContext;
+      EpcS11SapSgw::BearerContextToBeCreated bearerContext;
       bearerContext.epsBearerId =  bit->bearerId; 
       bearerContext.bearerLevelQos = bit->bearer; 
       bearerContext.tft = bit->tft;
-      bearersToBeSetup.push_back (bearerContext);
+      msg.bearerContextsToBeCreated.push_back (bearerContext);
     }
-  EpcS11Sap::Uli uli;
-  uli.gci = gci;
-  m_s11SapSgw->RecvCreateSessionRequest (imsi, uli, bearersToBeSetup);
+  m_s11SapSgw->CreateSessionRequest (msg);
 }
 
 void 
@@ -158,19 +158,32 @@
 EpcMme::DoPathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list<EpcS1apSapMme::ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList)
 {
   NS_LOG_FUNCTION (this << mmeUeS1Id << enbUeS1Id << gci);
-  NS_FATAL_ERROR ("unimplemented");
+
+  uint64_t imsi = mmeUeS1Id; 
+  std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
+  NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
+  NS_LOG_INFO ("IMSI " << imsi << " old eNB: " << it->second->cellId << ", new eNB: " << gci);
+  it->second->cellId = gci;
+  it->second->enbUeS1Id = enbUeS1Id;
+
+  EpcS11SapSgw::ModifyBearerRequestMessage msg;
+  msg.teid = imsi; // trick to avoid the need for allocating TEIDs on the S11 interface
+  msg.uli.gci = gci;
+  // bearer modification is not supported for now
+  m_s11SapSgw->ModifyBearerRequest (msg);
 }
 
 
 // S11 SAP MME forwarded methods
 
 void 
-EpcMme::DoRecvCreateSessionResponse (uint64_t imsi, std::list<EpcS11SapMme::BearerContext> bearerContextList)
+EpcMme::DoCreateSessionResponse (EpcS11SapMme::CreateSessionResponseMessage msg)
 {
-  NS_LOG_FUNCTION (this << imsi);
+  NS_LOG_FUNCTION (this << msg.teid);
+  uint64_t imsi = msg.teid;
   std::list<EpcS1apSapEnb::ErabToBeSetupItem> erabToBeSetupList;
-  for (std::list<EpcS11SapMme::BearerContext>::iterator bit = bearerContextList.begin ();
-       bit != bearerContextList.end ();
+  for (std::list<EpcS11SapMme::BearerContextCreated>::iterator bit = msg.bearerContextsCreated.begin ();
+       bit != msg.bearerContextsCreated.end ();
        ++bit)
     {
       EpcS1apSapEnb::ErabToBeSetupItem erab;
@@ -191,6 +204,21 @@
 }
 
 
-
+void 
+EpcMme::DoModifyBearerResponse (EpcS11SapMme::ModifyBearerResponseMessage msg)
+{
+  NS_LOG_FUNCTION (this << msg.teid);
+  NS_ASSERT (msg.cause == EpcS11SapMme::ModifyBearerResponseMessage::REQUEST_ACCEPTED);
+  uint64_t imsi = msg.teid;
+  std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
+  NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
+  uint64_t enbUeS1Id = it->second->enbUeS1Id;
+  uint64_t mmeUeS1Id = it->second->mmeUeS1Id;
+  uint16_t cgi = it->second->cellId;
+  std::list<EpcS1apSapEnb::ErabSwitchedInUplinkItem> erabToBeSwitchedInUplinkList; // unused for now
+  std::map<uint16_t, Ptr<EnbInfo> >::iterator jt = m_enbInfoMap.find (it->second->cellId);
+  NS_ASSERT_MSG (jt != m_enbInfoMap.end (), "could not find any eNB with CellId " << it->second->cellId);
+  jt->second->s1apSapEnb->PathSwitchRequestAcknowledge (enbUeS1Id, mmeUeS1Id, cgi, erabToBeSwitchedInUplinkList);
+}
 
 } // namespace ns3
--- a/src/lte/model/epc-mme.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-mme.h	Thu Nov 29 12:00:06 2012 +0100
@@ -118,7 +118,8 @@
 
 
   // S11 SAP MME forwarded methods
-  void DoRecvCreateSessionResponse (uint64_t imsi, std::list<EpcS11SapMme::BearerContext>);
+  void DoCreateSessionResponse (EpcS11SapMme::CreateSessionResponseMessage msg);
+  void DoModifyBearerResponse (EpcS11SapMme::ModifyBearerResponseMessage msg);
 
   /**
    * Hold info on an EPS bearer to be activated
--- a/src/lte/model/epc-s11-sap.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-s11-sap.h	Thu Nov 29 12:00:06 2012 +0100
@@ -36,6 +36,11 @@
 
   virtual ~EpcS11Sap ();
 
+  struct GtpcMessage
+  {
+    uint32_t teid;
+  };
+
   /**
    * Fully-qualified TEID, see 3GPP TS 29.274 section 8.22
    * 
@@ -64,7 +69,7 @@
  * MME side of the S11 Service Access Point (SAP), provides the MME
  * methods to be called when an S11 message is received by the MME. 
  */
-  class EpcS11SapMme : public EpcS11Sap
+class EpcS11SapMme : public EpcS11Sap
 {
 public:
   
@@ -72,7 +77,7 @@
    * 3GPP TS 29.274 version 8.3.1 Release 8 section 8.28
    * 
    */
-  struct BearerContext
+  struct BearerContextCreated
   {
 
     EpcS11Sap::Fteid sgwFteid;
@@ -81,7 +86,43 @@
     Ptr<EpcTft> tft;
   };
 
-  virtual void RecvCreateSessionResponse (uint64_t imsi, std::list<BearerContext> bearerContextList) = 0;
+
+  /**     
+   * Create Session Response message, see 3GPP TS 29.274 7.2.2
+   */
+  struct CreateSessionResponseMessage : public GtpcMessage
+  {
+    std::list<BearerContextCreated> bearerContextsCreated;
+  };
+
+
+  /** 
+   * send a Create Session Response message
+   * 
+   * \params msg the message
+   */
+  virtual void CreateSessionResponse (CreateSessionResponseMessage msg) = 0;
+
+
+  /**     
+   * Modify Bearer Response message, see 3GPP TS 29.274 7.2.7
+   */
+  struct ModifyBearerResponseMessage : public GtpcMessage
+  {
+    enum Cause {
+      REQUEST_ACCEPTED = 0,
+      REQUEST_ACCEPTED_PARTIALLY,
+      REQUEST_REJECTED,
+      CONTEXT_NOT_FOUND
+    } cause;
+  };
+
+  /** 
+   * send a Modify Bearer Response message
+   * 
+   * \params msg the message
+   */
+  virtual void ModifyBearerResponse (ModifyBearerResponseMessage msg) = 0;
 
 };
 
@@ -95,36 +136,47 @@
 {
 public:
 
-  struct BearerContext
-  {
-    
+  struct BearerContextToBeCreated
+  {    
     EpcS11Sap::Fteid sgwFteid;
     uint8_t epsBearerId; 
     EpsBearer bearerLevelQos; 
     Ptr<EpcTft> tft;
   };
 
+  
+  /**     
+   * Create Session Request message, see 3GPP TS 29.274 7.2.1
+   */
+  struct CreateSessionRequestMessage : public GtpcMessage
+  {
+    uint64_t imsi; 
+    Uli uli; 
+    std::list<BearerContextToBeCreated> bearerContextsToBeCreated;    
+  };
+
   /** 
-   * 
+   * send a Create Session Request message
    * 
-   * \param imsi
-   * \param uli theoretically, the User Location Information (ULI) which
-   * includes the EGCI. In practice, we use the Cell Id. 
-   * \param bearersToBeSetup default bearer + eventual other bearers
-   * to be setup
+   * \params msg the message
    */
-  virtual void RecvCreateSessionRequest (uint64_t imsi, Uli uli, std::list<BearerContext> bearersToBeSetup) = 0;
+  virtual void CreateSessionRequest (CreateSessionRequestMessage msg) = 0;
 
 
+  /**     
+   * Modify Bearer Request message, see 3GPP TS 29.274 7.2.7
+   */
+  struct ModifyBearerRequestMessage : public GtpcMessage
+  {
+    Uli uli;
+  };
+
   /** 
-   * 
+   * send a Modify Bearer Request message
    * 
-   * \param imsi not included in the specs, we add it for simplicity.
-   * \param uli theoretically, the User Location Information (ULI) which
-   * includes the EGCI. In practice, we use the Cell Id. 
-   * \param bearersToBeSetup 
+   * \params msg the message
    */
-  virtual void ModifyBearerRequest (uint64_t mei, Uli uli, std::list<BearerContext> bearersToBeSetup) = 0;
+  virtual void ModifyBearerRequest (ModifyBearerRequestMessage msg) = 0;
 
 };
 
@@ -146,7 +198,8 @@
   MemberEpcS11SapMme (C* owner);
 
   // inherited from EpcS11SapMme
-  void RecvCreateSessionResponse (uint64_t imsi, std::list<BearerContext>);
+  virtual void CreateSessionResponse (CreateSessionResponseMessage msg);
+  virtual void ModifyBearerResponse (ModifyBearerResponseMessage msg);
 
 private:
   MemberEpcS11SapMme ();
@@ -165,9 +218,15 @@
 }
 
 template <class C>
-void MemberEpcS11SapMme<C>::RecvCreateSessionResponse (uint64_t imsi, std::list<BearerContext> bearerContextList)
+void MemberEpcS11SapMme<C>::CreateSessionResponse (CreateSessionResponseMessage msg)
 {
-  m_owner->DoRecvCreateSessionResponse (imsi, bearerContextList);
+  m_owner->DoCreateSessionResponse (msg);
+}
+
+template <class C>
+void MemberEpcS11SapMme<C>::ModifyBearerResponse (ModifyBearerResponseMessage msg)
+{
+  m_owner->DoModifyBearerResponse (msg);
 }
 
 
@@ -186,8 +245,8 @@
   MemberEpcS11SapSgw (C* owner);
 
   // inherited from EpcS11SapSgw
-  virtual void RecvCreateSessionRequest (uint64_t imsi, Uli uli, std::list<BearerContext> bearersToBeSetup);
-  virtual void ModifyBearerRequest (uint64_t mei, Uli uli, std::list<BearerContext> bearersToBeSetup);
+  virtual void CreateSessionRequest (CreateSessionRequestMessage msg);
+  virtual void ModifyBearerRequest (ModifyBearerRequestMessage msg);
 
 private:
   MemberEpcS11SapSgw ();
@@ -206,15 +265,15 @@
 }
 
 template <class C>
-void MemberEpcS11SapSgw<C>::RecvCreateSessionRequest (uint64_t imsi, Uli uli, std::list<BearerContext> bearersToBeSetup)
+void MemberEpcS11SapSgw<C>::CreateSessionRequest (CreateSessionRequestMessage msg)
 {
-  m_owner->DoRecvCreateSessionRequest (imsi, uli, bearersToBeSetup);
+  m_owner->DoCreateSessionRequest (msg);
 }
 
 template <class C>
-void MemberEpcS11SapSgw<C>::ModifyBearerRequest (uint64_t mei, Uli uli, std::list<BearerContext> bearersToBeSetup)
+void MemberEpcS11SapSgw<C>::ModifyBearerRequest (ModifyBearerRequestMessage msg)
 {
-  m_owner->DoModifyBearerRequest (mei, uli, bearersToBeSetup);
+  m_owner->DoModifyBearerRequest (msg);
 }
 
 
--- a/src/lte/model/epc-s1ap-sap.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-s1ap-sap.h	Thu Nov 29 12:00:06 2012 +0100
@@ -59,15 +59,20 @@
    */
   virtual void InitialUeMessage (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, uint64_t imsi, uint16_t ecgi) = 0;
 
+
+  /**
+   *  E-RAB Setup Item IEs, see 3GPP TS 36.413 9.1.4.2 
+   * 
+   */
   struct ErabSetupItem
   {
     uint16_t    erabId;
-    Ipv4Address transportLayerAddress;
+    Ipv4Address enbTransportLayerAddress;
     uint32_t    enbTeid;    
   };
 
   /** 
-   * 
+   * INITIAL CONTEXT SETUP RESPONSE message,  see 3GPP TS 36.413 9.1.4.2 
    * 
    * \param mmeUeS1Id in practice, we use the IMSI
    * \param enbUeS1Id in practice, we use the RNTI
@@ -84,7 +89,7 @@
   struct ErabSwitchedInDownlinkItem
   {
     uint16_t    erabId;
-    Ipv4Address transportLayerAddress;
+    Ipv4Address enbTransportLayerAddress;
     uint32_t    enbTeid;    
   };
 
@@ -92,7 +97,7 @@
    * PATH SWITCH REQUEST message, see 3GPP TS 36.413 9.1.5.8
    * 
    */
-  virtual void PathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t cgi, std::list<ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList) = 0;
+  virtual void PathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list<ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList) = 0;
 };
 
 
--- a/src/lte/model/epc-sgw-pgw-application.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-sgw-pgw-application.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -44,9 +44,10 @@
 }
 
 void
-EpcSgwPgwApplication::UeInfo::AddBearer (Ptr<EpcTft> tft, uint32_t teid)
+EpcSgwPgwApplication::UeInfo::AddBearer (Ptr<EpcTft> tft, uint8_t bearerId, uint32_t teid)
 {
   NS_LOG_FUNCTION (this << tft << teid);
+  m_teidByBearerIdMap[bearerId] = teid;
   return m_tftClassifier.Add (tft, teid);
 }
 
@@ -125,23 +126,6 @@
 }
 
 
-uint32_t 
-EpcSgwPgwApplication::ActivateS1Bearer (Ipv4Address ueAddr, Ipv4Address enbAddr, Ptr<EpcTft> tft)
-{
-  NS_LOG_FUNCTION (this << ueAddr << enbAddr << tft);
-
-  // simple sanity check. If you ever need more than 4M teids
-  // throughout your simulation, you'll need to implement a smarter teid
-  // management algorithm. 
-  NS_ABORT_IF (m_teidCount == 0xFFFFFFFF);
-  uint32_t teid = ++m_teidCount;  
-
-  std::map<Ipv4Address, Ptr<UeInfo> >::iterator it = m_ueInfoByAddrMap.find (ueAddr);
-  NS_ASSERT (it != m_ueInfoByAddrMap.end ());       
-  it->second->AddBearer (tft, teid);
-  return teid;
-}
-
 bool
 EpcSgwPgwApplication::RecvFromTunDevice (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
 {
@@ -262,42 +246,60 @@
 }
 
 void 
-EpcSgwPgwApplication::DoRecvCreateSessionRequest (uint64_t imsi, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup)
+EpcSgwPgwApplication::DoCreateSessionRequest (EpcS11SapSgw::CreateSessionRequestMessage req)
 {
-  NS_LOG_FUNCTION (this << imsi);
-  std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
-  NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi); 
-  Ipv4Address ueAddr = ueit->second->GetUeAddr ();
-  uint16_t cellId = uli.gci;
+  NS_LOG_FUNCTION (this << req.imsi);
+  std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (req.imsi);
+  NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << req.imsi); 
+  uint16_t cellId = req.uli.gci;
   std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
   NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId); 
   Ipv4Address enbAddr = enbit->second.enbAddr;
   ueit->second->SetEnbAddr (enbAddr);
 
-  // bearer context info to be fed back to the MME in the response
-  std::list<EpcS11SapMme::BearerContext> bearersContextList;
+  EpcS11SapMme::CreateSessionResponseMessage res;
+  res.teid = req.imsi; // trick to avoid the need for allocating TEIDs on the S11 interface
 
-  for (std::list<EpcS11SapSgw::BearerContext>::iterator bit = bearersToBeSetup.begin ();
-       bit != bearersToBeSetup.end ();
+  for (std::list<EpcS11SapSgw::BearerContextToBeCreated>::iterator bit = req.bearerContextsToBeCreated.begin ();
+       bit != req.bearerContextsToBeCreated.end ();
        ++bit)
     {
-      uint32_t teid = ActivateS1Bearer (ueAddr, enbAddr, bit->tft);
-      EpcS11SapMme::BearerContext bearerContext;
+      // simple sanity check. If you ever need more than 4M teids
+      // throughout your simulation, you'll need to implement a smarter teid
+      // management algorithm. 
+      NS_ABORT_IF (m_teidCount == 0xFFFFFFFF);
+      uint32_t teid = ++m_teidCount;  
+      ueit->second->AddBearer (bit->tft, bit->epsBearerId, teid);
+
+      EpcS11SapMme::BearerContextCreated bearerContext;
       bearerContext.sgwFteid.teid = teid;
       bearerContext.sgwFteid.address = enbit->second.sgwAddr;
       bearerContext.epsBearerId =  bit->epsBearerId; 
       bearerContext.bearerLevelQos = bit->bearerLevelQos; 
       bearerContext.tft = bit->tft;
-      bearersContextList.push_back (bearerContext);
+      res.bearerContextsCreated.push_back (bearerContext);
     }
-  m_s11SapMme->RecvCreateSessionResponse (imsi, bearersContextList);
+  m_s11SapMme->CreateSessionResponse (res);
   
 }
 
 void 
-EpcSgwPgwApplication::DoModifyBearerRequest (uint64_t mei, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup)
+EpcSgwPgwApplication::DoModifyBearerRequest (EpcS11SapSgw::ModifyBearerRequestMessage req)
 {
-  NS_FATAL_ERROR ("not implemented");
+  NS_LOG_FUNCTION (this << req.teid);
+  uint64_t imsi = req.teid; // trick to avoid the need for allocating TEIDs on the S11 interface
+  std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
+  NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi); 
+  uint16_t cellId = req.uli.gci;
+  std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
+  NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId); 
+  Ipv4Address enbAddr = enbit->second.enbAddr;
+  ueit->second->SetEnbAddr (enbAddr);
+  // no actual bearer modification: for now we just support the minimum needed for path switch request (handover)
+  EpcS11SapMme::ModifyBearerResponseMessage res;
+  res.teid = imsi; // trick to avoid the need for allocating TEIDs on the S11 interface
+  res.cause = EpcS11SapMme::ModifyBearerResponseMessage::REQUEST_ACCEPTED;
+  m_s11SapMme->ModifyBearerResponse (res);
 }
  
 }; // namespace ns3
--- a/src/lte/model/epc-sgw-pgw-application.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-sgw-pgw-application.h	Thu Nov 29 12:00:06 2012 +0100
@@ -168,8 +168,8 @@
 private:
 
   // S11 SAP SGW methods
-  void DoRecvCreateSessionRequest (uint64_t imsi, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup);
-  void DoModifyBearerRequest (uint64_t mei, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup);  
+  void DoCreateSessionRequest (EpcS11SapSgw::CreateSessionRequestMessage msg);
+  void DoModifyBearerRequest (EpcS11SapSgw::ModifyBearerRequestMessage msg);  
 
   /**
    * store info for each UE connected to this SGW
@@ -182,9 +182,10 @@
     /** 
      * 
      * \param tft the Traffic Flow Template of the new bearer to be added
+     * \param epsBearerId the ID of the EPS Bearer to be activated
      * \param teid  the TEID of the new bearer
      */
-    void AddBearer (Ptr<EpcTft> tft, uint32_t teid);
+    void AddBearer (Ptr<EpcTft> tft, uint8_t epsBearerId, uint32_t teid);
 
     /** 
      * 
@@ -226,6 +227,7 @@
     EpcTftClassifier m_tftClassifier;
     Ipv4Address m_enbAddr;
     Ipv4Address m_ueAddr;
+    std::map<uint8_t, uint32_t> m_teidByBearerIdMap;
   };
 
 
--- a/src/lte/model/lte-enb-net-device.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-net-device.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -48,8 +48,6 @@
 
 NS_OBJECT_ENSURE_REGISTERED ( LteEnbNetDevice);
 
-uint16_t LteEnbNetDevice::m_cellIdCounter = 0;
-
 TypeId LteEnbNetDevice::GetTypeId (void)
 {
   static TypeId
@@ -250,8 +248,7 @@
 void 
 LteEnbNetDevice::DoStart (void)
 {
-  NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
-  m_cellId = ++m_cellIdCounter;
+
   UpdateConfig ();
   m_phy->Start ();
   m_mac->Start ();
--- a/src/lte/model/lte-enb-net-device.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-net-device.h	Thu Nov 29 12:00:06 2012 +0100
@@ -148,8 +148,6 @@
 
   uint16_t m_cellId; /**< Cell Identifer. Part of the CGI, see TS 29.274, section 8.21.1  */
 
-  static uint16_t m_cellIdCounter;
-
   uint8_t m_dlBandwidth; /**< downlink bandwidth in RBs */
   uint8_t m_ulBandwidth; /**< uplink bandwidth in RBs */
 
--- a/src/lte/model/lte-enb-rrc.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -103,6 +103,7 @@
     "CONNECTION_RECONFIGURATION",
     "CONNECTION_REESTABLISHMENT",
     "HANDOVER_JOINING",
+    "HANDOVER_PATH_SWITCH",
     "HANDOVER_LEAVING",
   };
 
@@ -263,6 +264,12 @@
   m_sourceCellId = sourceCellId;
 }
 
+void 
+UeManager::SetImsi (uint64_t imsi)
+{
+  m_imsi = imsi;
+}
+
 uint8_t
 UeManager::SetupDataRadioBearer (EpsBearer bearer, uint32_t gtpTeid, Ipv4Address transportLayerAddress)
 {
@@ -449,6 +456,31 @@
   return ret;
 }
 
+void
+UeManager::SendUeContextRelease ()
+{
+  NS_LOG_FUNCTION (this);
+  switch (m_state)
+    {     
+    case HANDOVER_PATH_SWITCH:
+      NS_LOG_INFO ("Send UE CONTEXT RELEASE from target eNB to source eNB");
+      EpcX2SapProvider::UeContextReleaseParams ueCtxReleaseParams;
+      ueCtxReleaseParams.oldEnbUeX2apId = m_sourceX2apId;
+      ueCtxReleaseParams.newEnbUeX2apId = m_rnti;
+      ueCtxReleaseParams.sourceCellId = m_sourceCellId;
+      m_rrc->m_x2SapProvider->SendUeContextRelease (ueCtxReleaseParams);
+      SwitchToState (CONNECTED_NORMALLY);
+      break;
+      
+    default:
+      NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
+      break;      
+    }
+}
+
+
+// methods forwarded from RRC SAP
+
 void 
 UeManager::CompleteSetupUe (LteEnbRrcSapProvider::CompleteSetupUeParameters params)
 {
@@ -515,13 +547,24 @@
       break;
       
     case HANDOVER_JOINING:
-      NS_LOG_INFO ("Send UE CONTEXT RELEASE from target eNB to source eNB");
-      EpcX2SapProvider::UeContextReleaseParams ueCtxReleaseParams;
-      ueCtxReleaseParams.oldEnbUeX2apId = m_sourceX2apId;
-      ueCtxReleaseParams.newEnbUeX2apId = m_rnti;
-      ueCtxReleaseParams.sourceCellId = m_sourceCellId;
-      m_rrc->m_x2SapProvider->SendUeContextRelease (ueCtxReleaseParams);
-      SwitchToState (CONNECTED_NORMALLY);
+      {
+        NS_LOG_INFO ("Send PATH SWITCH REQUEST to the MME");
+        EpcEnbS1SapProvider::PathSwitchRequestParameters params;
+        params.rnti = m_rnti;
+        params.cellId = m_rrc->m_cellId;
+        params.mmeUeS1Id = m_imsi;
+        SwitchToState (HANDOVER_PATH_SWITCH);
+        for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it =  m_drbMap.begin ();
+             it != m_drbMap.end ();
+             ++it)
+          {
+            EpcEnbS1SapProvider::BearerToBeSwitched b;
+            b.epsBearerId = it->second->m_epsBearerIdentity;
+            b.teid =  it->second->m_gtpTeid;
+            params.bearersToBeSwitched.push_back (b);
+          }     
+        m_rrc->m_s1SapProvider->PathSwitchRequest (params);
+      }
       break;
       
     default:
@@ -549,6 +592,8 @@
 }
 
 
+// methods forwarded from CMAC SAP
+
 void
 UeManager::CmacUeConfigUpdateInd (LteEnbCmacSapUser::UeConfig cmacParams)
 {
@@ -571,6 +616,8 @@
 }
 
 
+// methods forwarded from PDCP SAP
+
 void
 UeManager::DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params)
 {
@@ -1037,7 +1084,7 @@
   params.cause          = EpcX2SapProvider::HandoverDesirableForRadioReason;
   params.sourceCellId   = m_cellId;
   params.targetCellId   = cellId;
-  params.mmeUeS1apId    = 1234567;
+  params.mmeUeS1apId    = ueManager->GetImsi ();
   params.ueAggregateMaxBitRateDownlink = 200 * 1000;
   params.ueAggregateMaxBitRateUplink = 100 * 1000;
   params.bearers = ueManager->GetErabList ();
@@ -1110,6 +1157,12 @@
   ueManager->ScheduleRrcConnectionReconfiguration ();
 }
 
+void 
+LteEnbRrc::DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params)
+{
+  Ptr<UeManager> ueManager = GetUeManager (params.rnti);
+  ueManager->SendUeContextRelease ();
+}
 
 void
 LteEnbRrc::DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params)
@@ -1137,6 +1190,7 @@
 
   Ptr<UeManager> ueManager = GetUeManager (rnti);
   ueManager->SetSource (params.sourceCellId, params.oldEnbUeX2apId);
+  ueManager->SetImsi (params.mmeUeS1apId);
 
   for (std::vector <EpcX2Sap::ErabToBeSetupItem>::iterator it = params.bearers.begin ();
        it != params.bearers.end ();
--- a/src/lte/model/lte-enb-rrc.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.h	Thu Nov 29 12:00:06 2012 +0100
@@ -72,6 +72,7 @@
       CONNECTION_RECONFIGURATION,
       CONNECTION_REESTABLISHMENT,
       HANDOVER_JOINING,
+      HANDOVER_PATH_SWITCH,
       HANDOVER_LEAVING,
       NUM_STATES
     };
@@ -107,6 +108,13 @@
   void SetSource (uint16_t sourceCellId, uint16_t sourceX2apId);
 
   /** 
+   * Set the IMSI
+   * 
+   * \param imsi the IMSI
+   */
+  void SetImsi (uint64_t imsi);
+
+  /** 
    * Setup a new data radio bearer, including both the configuration
    * within the eNB and the necessary RRC signaling with the UE
    * 
@@ -174,6 +182,13 @@
    * \return a list of ERAB-to-be-setup items to be put in a X2 HO REQ message
    */
   std::vector<EpcX2Sap::ErabToBeSetupItem> GetErabList ();
+
+  /** 
+   * send the UE CONTEXT RELEASE X2 message to the source eNB, thus
+   * successfully terminating an X2 handover procedure 
+   * 
+   */
+  void SendUeContextRelease ();
   
 
   // methods forwarded from RRC SAP
@@ -537,8 +552,7 @@
 
   // S1 SAP methods
   void DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params);
-
-
+  void DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params);       
   // X2 SAP methods
   void DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params);
   void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
--- a/src/lte/model/lte-ue-net-device.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-ue-net-device.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -50,8 +50,6 @@
 
 NS_OBJECT_ENSURE_REGISTERED ( LteUeNetDevice);
 
-uint64_t LteUeNetDevice::m_imsiCounter = 0;
-
 
 TypeId LteUeNetDevice::GetTypeId (void)
 {
@@ -92,7 +90,7 @@
 }
 
 
-  LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas)
+  LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas, uint64_t imsi)
 {
   NS_LOG_FUNCTION (this);
   m_phy = phy;
@@ -100,7 +98,7 @@
   m_rrc = rrc;
   m_nas = nas;
   SetNode (node);
-  m_imsi = ++m_imsiCounter;
+  m_imsi = imsi;
 }
 
 LteUeNetDevice::~LteUeNetDevice (void)
--- a/src/lte/model/lte-ue-net-device.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-ue-net-device.h	Thu Nov 29 12:00:06 2012 +0100
@@ -62,9 +62,10 @@
    * \param mac the MAC entity
    * \param rrc the RRC entity
    * \param nas the NAS entity
+   * \param imsi the unique UE identifier
    * 
    */
-  LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas);
+  LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas, uint64_t imsi);
 
   virtual ~LteUeNetDevice (void);
   virtual void DoDispose ();
@@ -123,8 +124,6 @@
   Ptr<EpcUeNas> m_nas;
 
   uint64_t m_imsi;
-  static uint64_t m_imsiCounter;
-
   
 };
 
--- a/src/lte/model/lte-ue-phy.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-ue-phy.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -743,8 +743,8 @@
   m_uplinkSpectrumPhy->SetCellId (cellId);
 
   // configure DL for receing the BCH with the minimum bandwith
-  const uint8_t minDlBandwidth = 6;
-  Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, minDlBandwidth, m_noiseFigure);
+  m_dlBandwidth = 6;
+  Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
   m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
   m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);  
   
--- a/src/lte/test/lte-test-entities.cc	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/test/lte-test-entities.cc	Thu Nov 29 12:00:06 2012 +0100
@@ -659,7 +659,12 @@
 {
 
 }
+  
+void 
+EpcTestRrc::DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params)
+{
 
+}
 
 
 } // namespace ns3
--- a/src/lte/test/lte-test-entities.h	Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/test/lte-test-entities.h	Thu Nov 29 12:00:06 2012 +0100
@@ -290,7 +290,8 @@
 
   // S1 SAP methods
   void DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params);
-
+  void DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params);  
+  
   EpcEnbS1SapProvider* m_s1SapProvider;
   EpcEnbS1SapUser* m_s1SapUser;