revised LTE protocol stack for new RRC model
authorNicola Baldo <nbaldo@cttc.es>
Mon, 02 Jul 2012 18:25:11 +0200
changeset 9337 ae7126b266ce
parent 9336 349de59878ad
child 9338 1945247ad4dd
revised LTE protocol stack for new RRC model
src/lte/examples/lena-cqi-threshold.cc
src/lte/examples/lena-dual-stripe.cc
src/lte/examples/lena-fading.cc
src/lte/examples/lena-intercell-interference.cc
src/lte/examples/lena-pathloss-traces.cc
src/lte/examples/lena-profiling.cc
src/lte/examples/lena-rem-sector-antenna.cc
src/lte/examples/lena-rem.cc
src/lte/examples/lena-rlc-traces.cc
src/lte/examples/lena-simple-epc.cc
src/lte/examples/lena-simple.cc
src/lte/helper/epc-helper.cc
src/lte/helper/epc-helper.h
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.cc
src/lte/model/epc-enb-s1-sap.h
src/lte/model/epc-ue-nas.cc
src/lte/model/epc-ue-nas.h
src/lte/model/eps-bearer.cc
src/lte/model/eps-bearer.h
src/lte/model/lte-as-sap.cc
src/lte/model/lte-as-sap.h
src/lte/model/lte-enb-cphy-sap.cc
src/lte/model/lte-enb-cphy-sap.h
src/lte/model/lte-enb-mac.cc
src/lte/model/lte-enb-net-device.cc
src/lte/model/lte-enb-phy-sap.h
src/lte/model/lte-enb-phy.cc
src/lte/model/lte-enb-phy.h
src/lte/model/lte-enb-rrc.cc
src/lte/model/lte-enb-rrc.h
src/lte/model/lte-phy.cc
src/lte/model/lte-phy.h
src/lte/model/lte-rlc-um.h
src/lte/model/lte-ue-cmac-sap.h
src/lte/model/lte-ue-cphy-sap.cc
src/lte/model/lte-ue-cphy-sap.h
src/lte/model/lte-ue-mac.cc
src/lte/model/lte-ue-net-device.cc
src/lte/model/lte-ue-net-device.h
src/lte/model/lte-ue-phy-sap.h
src/lte/model/lte-ue-phy.cc
src/lte/model/lte-ue-phy.h
src/lte/model/lte-ue-rrc.cc
src/lte/model/lte-ue-rrc.h
src/lte/test/epc-test-s1u-downlink.cc
src/lte/test/epc-test-s1u-uplink.cc
src/lte/test/lte-test-entities.cc
src/lte/test/lte-test-entities.h
src/lte/test/lte-test-interference.cc
src/lte/test/lte-test-link-adaptation.cc
src/lte/test/lte-test-mimo.cc
src/lte/test/lte-test-pathloss-model.cc
src/lte/test/lte-test-pf-ff-mac-scheduler.cc
src/lte/test/lte-test-phy-error-model.cc
src/lte/test/lte-test-rr-ff-mac-scheduler.cc
src/lte/test/test-lte-antenna.cc
src/lte/test/test-lte-epc-e2e-data.cc
src/lte/wscript
--- a/src/lte/examples/lena-cqi-threshold.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-cqi-threshold.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -113,10 +113,10 @@
   Simulator::Schedule (Seconds (0.010), &ChangePosition, ueNodes.Get (0));
   Simulator::Schedule (Seconds (0.020), &ChangePosition, ueNodes.Get (0));
 
-  // Activate an EPS bearer
+  // Activate a data radio bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
 
   Simulator::Stop (Seconds (0.030));
--- a/src/lte/examples/lena-dual-stripe.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-dual-stripe.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -415,7 +415,8 @@
   mobility.SetPositionAllocator (positionAlloc);
   mobility.Install (macroUes);
   NetDeviceContainer macroUeDevs = lteHelper->InstallUeDevice (macroUes);
-  lteHelper->AttachToClosestEnb (macroUeDevs, macroEnbDevs);
+
+
 
 
   // home UEs located in the same apartment in which there are the Home eNBs
@@ -424,22 +425,7 @@
   mobility.Install (homeUes);
   NetDeviceContainer homeUeDevs = lteHelper->InstallUeDevice (homeUes);
 
-  NetDeviceContainer::Iterator ueDevIt;
-  NetDeviceContainer::Iterator enbDevIt = homeEnbDevs.Begin ();
-  // attach explicitly each home UE to its home eNB
-  for (ueDevIt = homeUeDevs.Begin (); 
-       ueDevIt != homeUeDevs.End ();
-       ++ueDevIt, ++enbDevIt)
-    {
-      // this because of the order in which SameRoomPositionAllocator
-      // will place the UEs
-      if (enbDevIt == homeEnbDevs.End ())
-        {
-          enbDevIt = homeEnbDevs.Begin ();
-        }
-      lteHelper->Attach (*ueDevIt, *enbDevIt);
-    }
-
+ 
 
   if (epc)
     {
@@ -549,14 +535,35 @@
     } // end if (epc)
 
 
- 
-  // activate bearer for all UEs
-  enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
-  EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (homeUeDevs, bearer, EpcTft::Default ());  
-  lteHelper->ActivateEpsBearer (macroUeDevs, bearer, EpcTft::Default ());
+  // attachment (needs to be done after IP stack configuration)
+  // macro UEs attached to the closest macro eNB
+  lteHelper->AttachToClosestEnb (macroUeDevs, macroEnbDevs);
+  // each home UE is ttach explicitly to its home eNB
+  NetDeviceContainer::Iterator ueDevIt;
+  NetDeviceContainer::Iterator enbDevIt = homeEnbDevs.Begin ();
+  
+  for (ueDevIt = homeUeDevs.Begin (); 
+       ueDevIt != homeUeDevs.End ();
+       ++ueDevIt, ++enbDevIt)
+    {
+      // this because of the order in which SameRoomPositionAllocator
+      // will place the UEs
+      if (enbDevIt == homeEnbDevs.End ())
+        {
+          enbDevIt = homeEnbDevs.Begin ();
+        }
+      lteHelper->Attach (*ueDevIt, *enbDevIt);
+    }
 
-
+  if (!epc)
+    {
+      // simplified LTE-only simulation
+      // need to activate radio bearers explicitly after attachment
+      enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
+      EpsBearer bearer (q);
+      lteHelper->ActivateDataRadioBearer (homeUeDevs, bearer);  
+      lteHelper->ActivateDataRadioBearer (macroUeDevs, bearer);      
+    }
 
   BuildingsHelper::MakeMobilityModelConsistent ();
 
--- a/src/lte/examples/lena-fading.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-fading.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -103,7 +103,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
 
   Simulator::Stop (Seconds (0.005));
--- a/src/lte/examples/lena-intercell-interference.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-intercell-interference.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -120,11 +120,11 @@
   lteHelper->Attach (ueDevs1, enbDevs.Get (0));
   lteHelper->Attach (ueDevs2, enbDevs.Get (1));
 
-  // Activate an EPS bearer on all UEs
+  // Activate a data radio bearer each UE
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs1, bearer, EpcTft::Default ());
-  lteHelper->ActivateEpsBearer (ueDevs2, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs1, bearer);
+  lteHelper->ActivateDataRadioBearer (ueDevs2, bearer);
 
   Simulator::Stop (Seconds (10));
 
--- a/src/lte/examples/lena-pathloss-traces.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-pathloss-traces.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -226,8 +226,8 @@
   // Activate an EPS bearer on all UEs
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs1, bearer, EpcTft::Default ());
-  lteHelper->ActivateEpsBearer (ueDevs2, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs1, bearer);
+  lteHelper->ActivateDataRadioBearer (ueDevs2, bearer);
 
   Simulator::Stop (Seconds (0.5));
 
--- a/src/lte/examples/lena-profiling.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-profiling.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -186,7 +186,7 @@
       lteHelper->Attach (ueDev, enbDevs.Get (i));
       enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
       EpsBearer bearer (q);
-      lteHelper->ActivateEpsBearer (ueDev, bearer, EpcTft::Default ());
+      lteHelper->ActivateDataRadioBearer (ueDev, bearer);
     }
 
 
--- a/src/lte/examples/lena-rem-sector-antenna.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-rem-sector-antenna.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -197,7 +197,7 @@
       lteHelper->Attach (ueDev, enbDevs.Get (i));
       enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
       EpsBearer bearer (q);
-      lteHelper->ActivateEpsBearer (ueDev, bearer, EpcTft::Default ());
+      lteHelper->ActivateDataRadioBearer (ueDev, bearer);
     }
 
 
--- a/src/lte/examples/lena-rem.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-rem.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -81,7 +81,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
 
   // Configure Radio Environment Map (REM) output
--- a/src/lte/examples/lena-rlc-traces.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-rlc-traces.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -73,7 +73,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
   Simulator::Stop (Seconds (2));
 
--- a/src/lte/examples/lena-simple-epc.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-simple-epc.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -113,12 +113,6 @@
   NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes);
   NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ueNodes);
 
-  // Attach one UE per eNodeB
-  for (uint16_t i = 0; i < numberOfNodes; i++)
-      {
-        lteHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(i));
-      }
-
   // Install the IP stack on the UEs
   internet.Install (ueNodes);
   Ipv4InterfaceContainer ueIpIface;
@@ -131,7 +125,13 @@
       Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
       ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
     }
-  lteHelper->ActivateEpsBearer (ueLteDevs, EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), EpcTft::Default ());
+
+  // Attach one UE per eNodeB
+  for (uint16_t i = 0; i < numberOfNodes; i++)
+      {
+        lteHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(i));
+        // side effect: the default EPS bearer will be activated
+      }
 
 
   // Install and start applications on UEs and remote host
--- a/src/lte/examples/lena-simple.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/examples/lena-simple.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -76,13 +76,12 @@
   // Attach a UE to a eNB
   lteHelper->Attach (ueDevs, enbDevs.Get (0));
 
-  // Activate an EPS bearer
+  // Activate a data radio bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
-
-  Simulator::Stop (Seconds (0.005));
+  Simulator::Stop (Seconds (0.010));
 
   Simulator::Run ();
 
--- a/src/lte/helper/epc-helper.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/helper/epc-helper.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -195,22 +195,34 @@
 }
 
 
+void 
+EpcHelper::AttachUe (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<NetDevice> enbDevice)
+{
+  NS_LOG_FUNCTION (this << ueLteDevice << enbDevice);
+
+  m_imsiEnbDeviceMap[imsi] = enbDevice;
+}
+
 void
-EpcHelper::ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, Ptr<NetDevice> enbLteDevice, Ptr<EpcTft> tft, uint16_t rnti, uint8_t lcid)
+EpcHelper::ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer)
 {
+  std::map<uint64_t, Ptr<NetDevice> >::iterator it = m_imsiEnbDeviceMap.find (imsi);
+  NS_ASSERT_MSG (it != m_imsiEnbDeviceMap.end (), "no eNB found for this IMSI, did you attach it before?");
+  Ptr<NetDevice> enbDevice = it->second;
   Ptr<Node> ueNode = ueLteDevice->GetNode (); 
   Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4> ();
+  NS_ASSERT_MSG (ueIpv4 != 0, "UEs need to have IPv4 installed before EPS bearers can be activated");
   int32_t interface =  ueIpv4->GetInterfaceForDevice (ueLteDevice);
   NS_ASSERT (interface >= 0);
   NS_ASSERT (ueIpv4->GetNAddresses (interface) == 1);
   Ipv4Address ueAddr = ueIpv4->GetAddress (interface, 0).GetLocal ();
   NS_LOG_LOGIC (" UE IP address: " << ueAddr);
 
-  // NOTE: unlike ueLteDevice, enbLteDevice is NOT an Ipv4 enabled
+  // NOTE: unlike ueLteDevice, enbDevice is NOT an Ipv4 enabled
   // device. In fact we are interested in the S1 device of the eNB.
   // We find it by relying on the assumption that the S1 device is the
   // only Ipv4 enabled device of the eNB besides the localhost interface.
-  Ptr<Node> enbNode = enbLteDevice->GetNode (); 
+  Ptr<Node> enbNode = enbDevice->GetNode (); 
   NS_ASSERT (enbNode != 0);
   Ptr<Ipv4> enbIpv4 = enbNode->GetObject<Ipv4> ();
   NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB: " << enbIpv4->GetNInterfaces ());
@@ -231,7 +243,7 @@
   NS_ASSERT (app != 0);
   Ptr<EpcEnbApplication> epcEnbApp = app->GetObject<EpcEnbApplication> ();
   NS_ASSERT (epcEnbApp != 0);
-  epcEnbApp->ErabSetupRequest (teid, rnti, lcid);
+  epcEnbApp->ErabSetupRequest (teid, imsi, bearer);
   
   
 }
--- a/src/lte/helper/epc-helper.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/helper/epc-helper.h	Mon Jul 02 18:25:11 2012 +0200
@@ -26,7 +26,7 @@
 #include <ns3/ipv4-address-helper.h>
 #include <ns3/data-rate.h>
 #include <ns3/epc-tft.h>
-
+#include <ns3/eps-bearer.h>
 
 namespace ns3 {
 
@@ -71,19 +71,28 @@
    */
   void AddEnb (Ptr<Node> enbNode, Ptr<NetDevice> lteEnbNetDevice);
 
+  /** 
+   * Simplified UE Attachment somewhat equivalent to NAS EMM Attach
+   * Request + ECM PDN Connectivity Request 
+   * 
+   * \param ueLteDevice the UE device to be attached
+   * \param imsi the unique identifier of the UE
+   * \param enbDevice the eNB to which the UE is currently connected
+   */
+  void AttachUe (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<NetDevice> enbDevice);
 
   /** 
    * Activate an EPS bearer, setting up the corresponding S1-U tunnel.
    * 
    * 
    * 
-   * \param ueLteDevice the Ipv4-enabled device of the UE, normally connected via the LTE radio interface
-   * \param enbLteDevice the non-Ipv4-enabled device of the eNB
+   * \param ueLteDevice the Ipv4-enabled device of the UE, normally
+   * connected via the LTE radio interface
+   * \param imsi the unique identifier of the UE
    * \param tft the Traffic Flow Template of the new bearer
-   * \param rnti the Radio Network Temporary Identifier that identifies the UE
-   * \param lcid the Logical Channel IDentifier of the corresponding RadioBearer
+   * \param bearer struct describing the characteristics of the EPS bearer to be activated
    */
-  void ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, Ptr<NetDevice> enbLteDevice, Ptr<EpcTft> tft, uint16_t rnti, uint8_t lcid);
+  void ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer);
 
 
   /** 
@@ -135,12 +144,17 @@
   Time     m_s1uLinkDelay;
   uint16_t m_s1uLinkMtu;
 
-
   /**
    * UDP port where the GTP-U Socket is bound, fixed by the standard as 2152
    */
   uint16_t m_gtpuUdpPort;
 
+  /**
+   * Map storing for each IMSI the corresponding eNB NetDevice
+   * 
+   */
+  std::map<uint64_t, Ptr<NetDevice> > m_imsiEnbDeviceMap;
+
 };
 
 
--- a/src/lte/helper/lte-helper.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/helper/lte-helper.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -26,6 +26,8 @@
 #include <ns3/abort.h>
 #include <ns3/pointer.h>
 #include <ns3/lte-enb-rrc.h>
+#include <ns3/epc-ue-nas.h>
+#include <ns3/epc-enb-application.h>
 #include <ns3/lte-ue-rrc.h>
 #include <ns3/lte-ue-mac.h>
 #include <ns3/lte-enb-mac.h>
@@ -43,6 +45,7 @@
 #include <ns3/lte-rlc.h>
 #include <ns3/lte-rlc-um.h>
 #include <ns3/lte-rlc-am.h>
+#include <ns3/epc-enb-s1-sap.h>
 
 #include <ns3/epc-helper.h>
 #include <iostream>
@@ -144,14 +147,6 @@
                    StringValue (""), // fake module -> no fading 
                    MakeStringAccessor (&LteHelper::SetFadingModel),
                    MakeStringChecker ())
-    .AddAttribute ("EpsBearerToRlcMapping", 
-                   "Specify which type of RLC will be used for each type of EPS bearer. ",
-                   EnumValue (RLC_SM_ALWAYS),
-                   MakeEnumAccessor (&LteHelper::m_epsBearerToRlcMapping),
-                   MakeEnumChecker (RLC_SM_ALWAYS, "RlcSmAlways",
-                                    RLC_UM_ALWAYS, "RlcUmAlways",
-                                    RLC_AM_ALWAYS, "RlcAmAlways",
-                                    PER_BASED,     "PacketErrorRateBased"))
   ;
   return tid;
 }
@@ -171,11 +166,6 @@
 {
   NS_LOG_FUNCTION (this << h);
   m_epcHelper = h;
-  // it does not make sense to use RLC/SM when also using the EPC
-  if (m_epsBearerToRlcMapping == RLC_SM_ALWAYS)
-    {
-      m_epsBearerToRlcMapping = RLC_UM_ALWAYS;
-    }
 }
 
 void 
@@ -341,6 +331,16 @@
   Ptr<FfMacScheduler> sched = m_schedulerFactory.Create<FfMacScheduler> ();
   Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc> ();
 
+  if (m_epcHelper != 0)
+    {
+      EnumValue epsBearerToRlcMapping;
+      rrc->GetAttribute ("EpsBearerToRlcMapping", epsBearerToRlcMapping);
+      // it does not make sense to use RLC/SM when also using the EPC
+      if (epsBearerToRlcMapping.Get () == LteEnbRrc::RLC_SM_ALWAYS)
+        {
+          rrc->SetAttribute ("EpsBearerToRlcMapping", EnumValue (LteEnbRrc::RLC_UM_ALWAYS));
+        }
+    }
 
   // connect SAPs
   rrc->SetLteEnbCmacSapProvider (mac->GetLteEnbCmacSapProvider ());
@@ -355,6 +355,10 @@
 
   phy->SetLteEnbPhySapUser (mac->GetLteEnbPhySapUser ());
   mac->SetLteEnbPhySapProvider (phy->GetLteEnbPhySapProvider ());
+
+
+  phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
+  rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
  
   Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
   dev->SetNode (n);
@@ -396,6 +400,12 @@
     {
       NS_LOG_INFO ("adding this eNB to the EPC");
       m_epcHelper->AddEnb (n, dev);
+      Ptr<EpcEnbApplication> enbApp = n->GetApplication (0)->GetObject<EpcEnbApplication> ();
+      NS_ASSERT_MSG (enbApp != 0, "cannot retrieve EpcEnbApplication");
+
+      // EPC SAPS
+      rrc->SetS1SapProvider (enbApp->GetS1SapProvider ());
+      enbApp->SetS1SapUser (rrc->GetS1SapUser ());
     }
 
   return dev;
@@ -424,7 +434,6 @@
   dlPhy->SetMobility (mm);
   ulPhy->SetMobility (mm);
 
-
   Ptr<AntennaModel> antenna = (m_ueAntennaModelFactory.Create ())->GetObject<AntennaModel> ();
   NS_ASSERT_MSG (antenna, "error in creating the AntennaModel object");
   dlPhy->SetAntenna (antenna);
@@ -432,8 +441,14 @@
 
   Ptr<LteUeMac> mac = CreateObject<LteUeMac> ();
   Ptr<LteUeRrc> rrc = CreateObject<LteUeRrc> ();
+  Ptr<EpcUeNas> nas = CreateObject<EpcUeNas> ();
+ 
+  nas->SetEpcHelper (m_epcHelper);
 
   // connect SAPs
+  nas->SetAsSapProvider (rrc->GetAsSapProvider ());
+  rrc->SetAsSapUser (nas->GetAsSapUser ());
+
   rrc->SetLteUeCmacSapProvider (mac->GetLteUeCmacSapProvider ());
   mac->SetLteUeCmacSapUser (rrc->GetLteUeCmacSapUser ());
   rrc->SetLteMacSapProvider (mac->GetLteMacSapProvider ());
@@ -441,14 +456,21 @@
   phy->SetLteUePhySapUser (mac->GetLteUePhySapUser ());
   mac->SetLteUePhySapProvider (phy->GetLteUePhySapProvider ());
 
-  Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc);
+  phy->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser ());
+  rrc->SetLteUeCphySapProvider (phy->GetLteUeCphySapProvider ());
+
+  Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc, nas);
   phy->SetDevice (dev);
   dlPhy->SetDevice (dev);
   ulPhy->SetDevice (dev);
+  nas->SetDevice (dev);
 
   n->AddDevice (dev);
   dlPhy->SetGenericPhyRxEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, phy));
-  rrc->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev));
+  nas->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev));
+
+
+  dev->Start ();
 
   return dev;
 }
@@ -468,32 +490,18 @@
 LteHelper::Attach (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice)
 {
   NS_LOG_FUNCTION (this);
-  // setup RRC connection
-  Ptr<LteEnbRrc> enbRrc = enbDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
-  uint16_t rnti = enbRrc->AddUe (ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ());
-  Ptr<LteUeRrc> ueRrc = ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ();
-  ueRrc->ConfigureUe (rnti, enbDevice->GetObject<LteEnbNetDevice> ()->GetCellId () );
 
-  // attach UE to eNB
-  ueDevice->GetObject<LteUeNetDevice> ()->SetTargetEnb (enbDevice->GetObject<LteEnbNetDevice> ());
-
+  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
+  Ptr<EpcUeNas> ueNas = ueLteDevice->GetNas ();
+  ueNas->Connect (enbDevice);
 
-  // connect at the PHY layer
-  Ptr<LteEnbPhy> enbPhy = enbDevice->GetObject<LteEnbNetDevice> ()->GetPhy ();
-  Ptr<LteUePhy> uePhy = ueDevice->GetObject<LteUeNetDevice> ()->GetPhy ();
-  enbPhy->AddUePhy (rnti, uePhy);
+  m_downlinkChannel->AddRx (ueLteDevice->GetPhy ()->GetDownlinkSpectrumPhy ());
 
-//  
-  // WILD HACK - should be done through PHY SAP, probably passing by RRC
-  uePhy->SetRnti (rnti);
-  uePhy->DoSetBandwidth (enbDevice->GetObject<LteEnbNetDevice> ()->GetUlBandwidth (),
-                         enbDevice->GetObject<LteEnbNetDevice> ()->GetDlBandwidth ());
-  uePhy->DoSetEarfcn (enbDevice->GetObject<LteEnbNetDevice> ()->GetDlEarfcn (),
-                      enbDevice->GetObject<LteEnbNetDevice> ()->GetUlEarfcn ());
-
-  ueDevice->Start ();
-  
-  m_downlinkChannel->AddRx (uePhy->GetDownlinkSpectrumPhy ());
+  // tricks needed for the simplified LTE-only simulations 
+  if (m_epcHelper == 0)
+    {
+      ueDevice->GetObject<LteUeNetDevice> ()->SetTargetEnb (enbDevice->GetObject<LteEnbNetDevice> ());
+    }
 }
 
 void
@@ -529,68 +537,48 @@
 }
 
 void
-LteHelper::ActivateEpsBearer (NetDeviceContainer ueDevices, EpsBearer bearer, Ptr<EpcTft> tft)
+LteHelper::ActivateDedicatedEpsBearer (NetDeviceContainer ueDevices, EpsBearer bearer, Ptr<EpcTft> tft)
 {
   NS_LOG_FUNCTION (this);
   for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
     {
-      ActivateEpsBearer (*i, bearer, tft);
+      ActivateDedicatedEpsBearer (*i, bearer, tft);
     }
 }
 
 
 void
-LteHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft)
+LteHelper::ActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft)
 {
   NS_LOG_FUNCTION (this);
-  NS_LOG_INFO (" setting up Radio Bearer");
-  Ptr<LteEnbNetDevice> enbDevice = ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
-  Ptr<LteEnbRrc> enbRrc = enbDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
-  Ptr<LteUeRrc> ueRrc = ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ();
-  uint16_t rnti = ueRrc->GetRnti ();
-  TypeId rlcTypeId = GetRlcType (bearer);
-  uint8_t lcid = enbRrc->SetupRadioBearer (rnti, bearer, rlcTypeId);
-  ueRrc->SetupRadioBearer (rnti, bearer, rlcTypeId, lcid, tft);
 
-  if (m_epcHelper != 0)
-    {
-      NS_LOG_INFO (" setting up S1 Bearer");
-      m_epcHelper->ActivateEpsBearer (ueDevice, enbDevice, tft, rnti, lcid);
+  NS_ASSERT_MSG (m_epcHelper != 0, "dedicated EPS bearers cannot be set up when EPC is not used");
+  
+  ueDevice->GetObject<LteUeNetDevice> ()->ActivateDedicatedEpsBearer (bearer, tft);
 
-    }
 }
 
-TypeId
-LteHelper::GetRlcType (EpsBearer bearer)
+void 
+LteHelper::ActivateDataRadioBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer)
 {
-  switch (m_epsBearerToRlcMapping)
-    {
-    case RLC_SM_ALWAYS:
-      return LteRlcSm::GetTypeId ();
-      break;
-
-    case  RLC_UM_ALWAYS:
-      return LteRlcUm::GetTypeId ();
-      break;
+  NS_LOG_FUNCTION (this << ueDevice);
+  NS_ASSERT_MSG (m_epcHelper == 0, "this method must not be used when EPC is being used");
+  Ptr<LteEnbNetDevice> enbDevice = ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
+  Ptr<LteEnbRrc> enbRrc = enbDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
+  EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
+  params.imsi = ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ();
+  params.bearer = bearer;
+  params.teid = 0; // don't care
+  enbRrc->GetS1SapUser ()->DataRadioBearerSetupRequest (params);
+}
 
-    case RLC_AM_ALWAYS:
-      return LteRlcAm::GetTypeId ();
-      break;
-
-    case PER_BASED:
-      if (bearer.GetPacketErrorLossRate () > 1.0e-5)
-        {
-          return LteRlcUm::GetTypeId ();
-        }
-      else
-        {
-          return LteRlcAm::GetTypeId ();
-        }
-      break;
-
-    default:
-      return LteRlcSm::GetTypeId ();
-      break;
+void 
+LteHelper::ActivateDataRadioBearer (NetDeviceContainer ueDevices, EpsBearer bearer)
+{
+  NS_LOG_FUNCTION (this);
+   for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
+    {
+      ActivateDataRadioBearer (*i, bearer);
     }
 }
 
--- a/src/lte/helper/lte-helper.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/helper/lte-helper.h	Mon Jul 02 18:25:11 2012 +0200
@@ -178,7 +178,9 @@
   void Attach (NetDeviceContainer ueDevices, Ptr<NetDevice> enbDevice);
 
   /**
-   * Attach a UE device to an eNB device
+   * Attach a UE to the network
+   *
+   * Attach a UE device to the network via a given eNB, and activate the default EPS bearer.
    *
    * \param ueDevice
    * \param enbDevice
@@ -186,7 +188,9 @@
   void Attach (Ptr<NetDevice> ueDevice, Ptr<NetDevice> enbDevice);
 
   /** 
-   * Attach each UE in a set to the closest (w.r.t. distance) eNB among those in a set
+   * Attach each UE in a set to the closest (w.r.t. distance) eNB among those in a set.
+   * 
+   * 
    * 
    * \param ueDevices the set of UEs
    * \param enbDevices the set of eNBs
@@ -195,6 +199,8 @@
 
   /** 
    * Attach an UE ito the closest (w.r.t. distance) eNB among those in a set
+   * Will call LteHelper::Attach () passing to it the single eNB
+   * instance which resulted to be the closest to the UE 
    * 
    * \param ueDevice the UE
    * \param enbDevices the set of eNBs
@@ -202,30 +208,42 @@
   void AttachToClosestEnb (Ptr<NetDevice> ueDevice, NetDeviceContainer enbDevices);
 
   /**
-   * Activate an EPS bearer on a given set of UE devices
+   * Activate a dedicated EPS bearer on a given set of UE devices
+   *
+   * \param ueDevices the set of UE devices
+   * \param bearer the characteristics of the bearer to be activated
+   * \param tft the Traffic Flow Template that identifies the traffic to go on this bearer
+   */
+  void ActivateDedicatedEpsBearer (NetDeviceContainer ueDevices, EpsBearer bearer, Ptr<EpcTft> tft);
+
+  /**
+   * Activate a dedicated EPS bearer on a given UE device
    *
    * \param ueDevices the set of UE devices
    * \param bearer the characteristics of the bearer to be activated
    * \param tft the Traffic Flow Template that identifies the traffic to go on this bearer
    */
-  void ActivateEpsBearer (NetDeviceContainer ueDevices, EpsBearer bearer, Ptr<EpcTft> tft);
-
-  /**
-   * Activate an EPS bearer on a given UE device
-   *
-   * \param ueDevices the set of UE devices
-   * \param bearer the characteristics of the bearer to be activated
-   * \param tft the Traffic Flow Template that identifies the traffic to go on this bearer
-   */
-  void ActivateEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft);
+  void ActivateDedicatedEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft);
 
   /** 
-   * 
-   * \param bearer the specification of an EPS bearer
+   * Activate a Data Radio Bearer for a simplified LTE-only simulation
+   * without EPC.
    * 
-   * \return the type of RLC that is to be created for the given EPS bearer
+   * \param ueDevice the device of the UE for which the radio bearer
+   * is to be activated
+   * \param bearer the characteristics of the bearer to be activated
    */
-  TypeId GetRlcType (EpsBearer bearer);
+  void ActivateDataRadioBearer (Ptr<NetDevice> ueDevice,  EpsBearer bearer);
+
+
+  /** 
+   * Call ActivateDataRadioBearer (ueDevice, bearer) for each UE
+   * device in a given set
+   * 
+   * \param ueDevices the set of UE devices
+   * \param bearer
+   */
+  void ActivateDataRadioBearer (NetDeviceContainer ueDevices,  EpsBearer bearer);
 
   /** 
    * 
@@ -307,11 +325,6 @@
    */
   Ptr<RadioBearerStatsCalculator> GetPdcpStats (void);
 
-  enum LteEpsBearerToRlcMapping_t {RLC_SM_ALWAYS = 1,
-                                   RLC_UM_ALWAYS = 2,
-                                   RLC_AM_ALWAYS = 3,
-                                   PER_BASED = 4};
-
 protected:
   // inherited from Object
   virtual void DoStart (void);
@@ -344,8 +357,6 @@
   Ptr<RadioBearerStatsCalculator> m_rlcStats;
   Ptr<RadioBearerStatsCalculator> m_pdcpStats;
 
-  enum LteEpsBearerToRlcMapping_t m_epsBearerToRlcMapping;
-
   Ptr<EpcHelper> m_epcHelper;
 
 };
--- a/src/lte/model/epc-enb-application.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/epc-enb-application.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -26,8 +26,10 @@
 #include "ns3/ipv4.h"
 #include "ns3/inet-socket-address.h"
 #include "ns3/uinteger.h"
-#include "ns3/epc-gtpu-header.h"
-#include "ns3/lte-radio-bearer-tag.h"
+
+#include "epc-gtpu-header.h"
+#include "lte-radio-bearer-tag.h"
+
 
 namespace ns3 {
 
@@ -51,6 +53,7 @@
   NS_LOG_FUNCTION (this << lteSocket << s1uSocket << sgwAddress);
   m_s1uSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromS1uSocket, this));
   m_lteSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromLteSocket, this));
+  m_s1SapProvider = new MemberEpcEnbS1SapProvider<EpcEnbApplication> (this);
 }
 
 
@@ -58,15 +61,41 @@
 {
   NS_LOG_FUNCTION (this);
 }
- 
+
+
 void 
-EpcEnbApplication::ErabSetupRequest (uint32_t teid, uint16_t rnti, uint8_t lcid)
+EpcEnbApplication::SetS1SapUser (EpcEnbS1SapUser * s)
+{
+  m_s1SapUser = s;
+}
+
+  
+EpcEnbS1SapProvider* 
+EpcEnbApplication::GetS1SapProvider ()
+{
+  return m_s1SapProvider;
+}
+
+void 
+EpcEnbApplication::ErabSetupRequest (uint32_t teid, uint64_t imsi, EpsBearer bearer)
 {
-  NS_LOG_FUNCTION (this << teid << rnti << (uint16_t) lcid);
-  LteFlowId_t rbid (rnti, lcid);
+  NS_LOG_FUNCTION (this << teid << imsi);
+  // request the RRC to setup a radio bearer
+  struct EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
+  params.imsi = imsi;
+  params.bearer = bearer;
+  params.teid = teid;
+  m_s1SapUser->DataRadioBearerSetupRequest (params);
+}
+
+void 
+EpcEnbApplication::DoDataRadioBearerSetupResponse (EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters params)
+{
+  NS_ASSERT_MSG (params.success, "Radio Bearer Setup failed");  
+  LteFlowId_t rbid (params.rnti, params.lcid);
   // side effect: create entries if not exist
-  m_rbidTeidMap[rbid] = teid;
-  m_teidRbidMap[teid] = rbid;
+  m_rbidTeidMap[rbid] = params.teid;
+  m_teidRbidMap[params.teid] = rbid;
 }
 
 void 
--- a/src/lte/model/epc-enb-application.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/epc-enb-application.h	Mon Jul 02 18:25:11 2012 +0200
@@ -31,9 +31,14 @@
 #include <ns3/object.h>
 #include <ns3/lte-common.h>
 #include <ns3/application.h>
+#include <ns3/eps-bearer.h>
+#include <ns3/epc-enb-s1-sap.h>
 #include <map>
 
 namespace ns3 {
+class EpcEnbS1SapUser;
+class EpcEnbS1SapProvider;
+
 
 /**
  * \ingroup lte
@@ -67,16 +72,37 @@
   virtual ~EpcEnbApplication (void);
 
 
+  /** 
+   * Set the S1 SAP User
+   * 
+   * \param s the S1 SAP User
+   */
+  void SetS1SapUser (EpcEnbS1SapUser * s);
+
+  /** 
+   * 
+   * \return the S1 SAP Provider
+   */
+  EpcEnbS1SapProvider* GetS1SapProvider ();
+
+
+  /** 
+   * \see EpcEnbS1SapUser::DataRadioBearerSetupResponse
+   * 
+   * \param params 
+   */
+  void DoDataRadioBearerSetupResponse (EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters params);
 
   /** 
    * This method is triggered after the eNB received
-   * a S1-AP message of type E-RAB Setup Request by the MME and the RadioBearer has already been created
+   * a S1-AP message of type E-RAB Setup Request by the MME and will
+   * trigger the corresponding RadioBearer creation 
    * 
    * \param teid the Tunnel Endpoint IDentifier of the S1-bearer to be setup.
-   * \param rnti the unique ID of the UE on this eNB
-   * \param lcid the Logical Channel ID identifying the Radio Bearer
+   * \param imsi the unique ID of the UE
+   * \param bearer the specification of the corresponding EPS bearer
    */
-  void ErabSetupRequest (uint32_t teid, uint16_t rnti, uint8_t lcid);
+  void ErabSetupRequest (uint32_t teid, uint64_t imsi, EpsBearer bearer);
 
   /** 
    * Method to be assigned to the recv callback of the LTE socket. It is called when the eNB receives a data packet from the radio interface that is to be forwarded to the SGW.
@@ -146,6 +172,17 @@
    */
   uint16_t m_gtpuUdpPort;
 
+  /**
+   * Provider for the S1 SAP 
+   */
+  EpcEnbS1SapProvider* m_s1SapProvider;
+
+  /**
+   * User for the S1 SAP 
+   */
+  EpcEnbS1SapUser* m_s1SapUser;
+
+
 };
 
 } //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/epc-enb-s1-sap.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,33 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/epc-enb-s1-sap.h"
+
+namespace ns3 {
+
+EpcEnbS1SapProvider::~EpcEnbS1SapProvider ()
+{
+}
+
+EpcEnbS1SapUser::~EpcEnbS1SapUser ()
+{
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/epc-enb-s1-sap.h	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,185 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef EPC_ENB_S1_SAP_H
+#define EPC_ENB_S1_SAP_H
+
+#include <stdint.h>
+#include <ns3/eps-bearer.h>
+
+namespace ns3 {
+
+
+/**
+ * This class implements the Service Access Point (SAP) between the
+ * LteEnbRrc and the EpcEnbApplication. In particular, this class implements the
+ * Provider part of the SAP, i.e., the methods exported by the
+ * EpcEnbApplication and called by the LteEnbRrc.
+ * 
+ */
+class EpcEnbS1SapProvider
+{
+public:
+  virtual ~EpcEnbS1SapProvider ();
+  
+  /**
+   * Parameters passed to DataRadioBearerSetupResponse ()
+   * 
+   */
+  struct DataRadioBearerSetupResponseParameters
+  {
+    bool success; /**< true if DataRadioBearer was setup
+		     successfully, false otherwise*/
+    uint16_t rnti; /**< the RNTI corresponding to the IMSI for which
+                      the radio bearer activation was requested */
+    uint8_t lcid; /**< the LCID of the newly created radio bearer */
+
+    uint32_t teid; /**< context information that was passed upon the
+                      corresponding call to
+                      EpcEnbS1SapUser::DataRadioBearerSetupRequest  */
+  };
+
+  /**
+   * response after a call to
+   * EpcEnbS1SapUser::DataRadioBearerSetupRequest ()
+   * 
+   */
+  virtual void DataRadioBearerSetupResponse (DataRadioBearerSetupResponseParameters params) = 0;
+  
+};
+  
+
+
+/**
+ * This class implements the Service Access Point (SAP) between the
+ * LteEnbRrc and the EpcEnbApplication. In particular, this class implements the
+ * User part of the SAP, i.e., the methods exported by the LteEnbRrc
+ * and called by the EpcEnbApplication.
+ * 
+ */
+class EpcEnbS1SapUser
+{
+public:
+  virtual ~EpcEnbS1SapUser ();
+  
+  /**
+   * Parameters passed to DataRadioBearerSetupRequest ()
+   * 
+   */
+  struct DataRadioBearerSetupRequestParameters
+  {
+    uint64_t imsi;   /**< the IMSI identifying the UE for which the
+			DataRadioBearer is to be created */ 
+    EpsBearer bearer; /**< the characteristics of the bearer to be set
+                         up */
+    uint32_t teid;   /**< context information that needs to be passed
+                      to the corresponding call to
+                      EpcEnbS1SapProvider::DataRadioBearerSetupResponse */ 
+  };
+
+  /**
+   * request the setup of a DataRadioBearer
+   * 
+   */
+  virtual void DataRadioBearerSetupRequest (DataRadioBearerSetupRequestParameters params) = 0;
+  
+};
+  
+
+
+
+/**
+ * Template for the implementation of the EpcEnbS1SapProvider as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberEpcEnbS1SapProvider : public EpcEnbS1SapProvider
+{
+public:
+  MemberEpcEnbS1SapProvider (C* owner);
+
+  // inherited from EpcEnbS1SapProvider
+  virtual void DataRadioBearerSetupResponse (DataRadioBearerSetupResponseParameters params);
+
+
+private:
+  MemberEpcEnbS1SapProvider ();
+  C* m_owner;
+};
+
+template <class C>
+MemberEpcEnbS1SapProvider<C>::MemberEpcEnbS1SapProvider (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberEpcEnbS1SapProvider<C>::MemberEpcEnbS1SapProvider ()
+{
+}
+
+template <class C>
+void MemberEpcEnbS1SapProvider<C>::DataRadioBearerSetupResponse (DataRadioBearerSetupResponseParameters params)
+{
+  m_owner->DoDataRadioBearerSetupResponse (params);
+}
+
+
+/**
+ * Template for the implementation of the EpcEnbS1SapUser as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberEpcEnbS1SapUser : public EpcEnbS1SapUser
+{
+public:
+  MemberEpcEnbS1SapUser (C* owner);
+
+  // inherited from EpcEnbS1SapUser
+  virtual void DataRadioBearerSetupRequest (DataRadioBearerSetupRequestParameters params);
+
+private:
+  MemberEpcEnbS1SapUser ();
+  C* m_owner;
+};
+
+template <class C>
+MemberEpcEnbS1SapUser<C>::MemberEpcEnbS1SapUser (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberEpcEnbS1SapUser<C>::MemberEpcEnbS1SapUser ()
+{
+}
+
+template <class C>
+void MemberEpcEnbS1SapUser<C>::DataRadioBearerSetupRequest (DataRadioBearerSetupRequestParameters params)
+{
+  m_owner->DoDataRadioBearerSetupRequest (params);
+}
+
+
+} // namespace ns3
+
+#endif // EPC_ENB_S1_SAP_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/epc-ue-nas.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,177 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/fatal-error.h>
+#include <ns3/log.h>
+
+#include <ns3/epc-helper.h>
+
+#include "lte-enb-net-device.h"
+#include "epc-ue-nas.h"
+#include "lte-as-sap.h"
+
+NS_LOG_COMPONENT_DEFINE ("EpcUeNas");
+
+namespace ns3 {
+
+
+
+NS_OBJECT_ENSURE_REGISTERED (EpcUeNas);
+
+EpcUeNas::EpcUeNas ()
+  : m_asSapProvider (0),
+    m_bidCounter (0)
+{
+  NS_LOG_FUNCTION (this);
+  m_asSapUser = new MemberLteAsSapUser<EpcUeNas> (this);
+}
+
+
+EpcUeNas::~EpcUeNas ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+EpcUeNas::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  delete m_asSapUser;
+  m_epcHelper = 0;
+}
+
+TypeId
+EpcUeNas::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::EpcUeNas")
+    .SetParent<Object> ()
+    .AddConstructor<EpcUeNas> ()
+  ;
+  return tid;
+}
+
+
+void 
+EpcUeNas::SetEpcHelper (Ptr<EpcHelper> epcHelper)
+{
+  m_epcHelper = epcHelper;
+}
+
+void 
+EpcUeNas::SetDevice (Ptr<NetDevice> dev)
+{
+  m_device = dev;
+}
+
+void 
+EpcUeNas::SetImsi (uint64_t imsi)
+{
+  m_imsi = imsi;
+}
+
+void
+EpcUeNas::SetAsSapProvider (LteAsSapProvider* s)
+{
+  m_asSapProvider = s;
+}
+
+LteAsSapUser* 
+EpcUeNas::GetAsSapUser ()
+{
+  return m_asSapUser;
+}
+
+void 
+EpcUeNas::SetForwardUpCallback (Callback <void, Ptr<Packet> > cb)
+{
+  m_forwardUpCallback = cb;
+}
+
+void 
+EpcUeNas::Connect (Ptr<NetDevice> enbDevice)
+{
+
+  // since RRC Idle Mode cell selection is not supported yet, we
+  // force the UE RRC to be camped on a specific eNB
+  Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
+  m_asSapProvider->ForceCampedOnEnb (enbLteDevice, enbLteDevice->GetCellId ());
+
+  // tell RRC to go into connected mode
+  m_asSapProvider->Connect ();
+
+  if (m_epcHelper)
+    {
+      m_epcHelper->AttachUe (m_device, m_imsi, enbDevice);
+      // also activate default EPS bearer
+      ActivateEpsBearer (EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), EpcTft::Default ());
+    }
+}
+
+void 
+EpcUeNas::ActivateEpsBearer (EpsBearer bearer, Ptr<EpcTft> tft)
+{
+  NS_ASSERT_MSG (m_bidCounter < 11, "cannot have more than 11 EPS bearers");
+  uint8_t bid = ++m_bidCounter;
+  m_epcHelper->ActivateEpsBearer (m_device, m_imsi, tft, bearer);
+  m_tftClassifier.Add (tft, bid);
+}
+
+bool
+EpcUeNas::Send (Ptr<Packet> packet)
+{
+  NS_LOG_FUNCTION (this << packet);
+  
+  uint32_t id = m_tftClassifier.Classify (packet, EpcTft::UPLINK);
+  NS_ASSERT ((id & 0xFFFFFF00) == 0);
+  uint8_t bid = (uint8_t) (id & 0x000000FF);
+  if (bid == 0)
+    {
+      return false;
+    }
+  else
+    {
+      m_asSapProvider->SendData (packet, bid); 
+      return true;
+    }
+}
+
+void 
+EpcUeNas::DoNotifyConnectionSuccessful ()
+{
+}
+
+void 
+EpcUeNas::DoNotifyConnectionFailed ()
+{
+  NS_FATAL_ERROR ("connection failed, it should not happen with the current model");
+}
+
+void
+EpcUeNas::DoRecvData (Ptr<Packet> packet)
+{
+  NS_LOG_FUNCTION (this);
+  m_forwardUpCallback (packet);
+}
+
+
+
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/epc-ue-nas.h	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,145 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef EPC_UE_NAS_H
+#define EPC_UE_NAS_H
+
+
+#include <ns3/object.h>
+#include <ns3/lte-as-sap.h>
+#include <ns3/epc-tft-classifier.h>
+
+namespace ns3 {
+
+
+class EpcHelper;
+
+class EpcUeNas : public Object
+{
+  friend class MemberLteAsSapUser<EpcUeNas>;
+public:
+
+  /** 
+   * Constructor
+   */
+  EpcUeNas ();
+
+  /** 
+   * Destructor
+   */
+  virtual ~EpcUeNas ();
+
+  // inherited from Object
+  virtual void DoDispose (void);
+  static TypeId GetTypeId (void);
+
+  /**
+   * set the EpcHelper with which the NAS will interact as if it were the MME 
+   * 
+   * \param epcHelper 
+   */
+  void SetEpcHelper (Ptr<EpcHelper> epcHelper);
+
+
+  /** 
+   * 
+   * \param dev the UE NetDevice
+   */
+  void SetDevice (Ptr<NetDevice> dev);
+
+  /** 
+   * 
+   * 
+   * \param imsi the unique UE identifier
+   */
+  void SetImsi (uint64_t imsi);
+
+  /** 
+   * Set the AS SAP provider to interact with the NAS entity
+   * 
+   * \param s the AS SAP provider
+   */
+  void SetAsSapProvider (LteAsSapProvider* s);
+
+  /** 
+   * 
+   * 
+   * \return the AS SAP user exported by this RRC
+   */
+  LteAsSapUser* GetAsSapUser ();
+
+  /** 
+   * set the callback used to forward data packets up the stack
+   * 
+   * \param cb the callback
+   */
+  void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
+ 
+  /** 
+   * instruct the NAS to go to EMM Registered + ECM Connected
+   * 
+   * 
+   * \param enbDevice the eNB through which to connect
+   */
+  void Connect (Ptr<NetDevice> enbDevice);
+
+  /** 
+   * Activate an EPS bearer
+   * 
+   * \param bearer the characteristics of the bearer to be created
+   * \param tft the TFT identifying the traffic that will go on this bearer
+   */
+  void ActivateEpsBearer (EpsBearer bearer, Ptr<EpcTft> tft);
+
+  /** 
+   * Enqueue an IP packet on the proper bearer for uplink transmission
+   * 
+   * \param p the packet
+   * 
+   * \return true if successful, false if an error occurred
+   */
+  bool Send (Ptr<Packet> p);
+ 
+private:
+  
+  // LTE AS SAP methods
+  void DoNotifyConnectionSuccessful ();
+  void DoNotifyConnectionFailed ();
+  void DoRecvData (Ptr<Packet> packet);
+
+  Ptr<EpcHelper> m_epcHelper;
+  Ptr<NetDevice> m_device;
+
+  uint64_t m_imsi;
+  
+  LteAsSapProvider* m_asSapProvider;
+  LteAsSapUser* m_asSapUser;
+
+  uint8_t m_bidCounter;
+  EpcTftClassifier m_tftClassifier;
+
+  Callback <void, Ptr<Packet> > m_forwardUpCallback;
+
+};
+
+
+} // namespace ns3
+
+#endif // EPC_UE_NAS_H
--- a/src/lte/model/eps-bearer.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/eps-bearer.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -30,6 +30,7 @@
 
 
 EpsBearer::EpsBearer ()
+  : qci (NGBR_VIDEO_TCP_DEFAULT)
 {
 }
 
--- a/src/lte/model/eps-bearer.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/eps-bearer.h	Mon Jul 02 18:25:11 2012 +0200
@@ -82,6 +82,12 @@
   AllocationRetentionPriority arp;
 
   /**
+   * Deault constructor. QCI will be initialized to NGBR_VIDEO_TCP_DEFAULT
+   * 
+   */
+  EpsBearer ();
+
+  /**
    *
    * @param x the QoS Class Indicator
    *
@@ -116,8 +122,6 @@
    */
   double  GetPacketErrorLossRate () const;
 
-private:
-  EpsBearer ();
 };
 
 } // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-as-sap.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,33 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/lte-as-sap.h"
+
+namespace ns3 {
+
+LteAsSapProvider::~LteAsSapProvider ()
+{
+}
+
+LteAsSapUser::~LteAsSapUser ()
+{
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-as-sap.h	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,223 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+
+#ifndef LTE_AS_SAP_H
+#define LTE_AS_SAP_H
+
+#include <stdint.h>
+#include <ns3/ptr.h>
+#include <ns3/packet.h>
+
+namespace ns3 {
+
+class LteEnbNetDevice;
+
+/**
+ * This class implements the Access Stratum (AS) Service Access Point
+ * (SAP), i.e., the interface between the EpcUeNas and the LteEnbRrc
+ * and the EpcEnbApplication. In particular, this class implements the 
+ * Provider part of the SAP, i.e., the methods exported by the
+ * LteEnbRrc and called by the EpcUeNas.
+ * 
+ */
+class LteAsSapProvider
+{
+public:
+  virtual ~LteAsSapProvider ();
+
+  /** 
+   * Force the RRC to stay camped on a certain eNB
+   * 
+   * \param enbDevice the eNB device (wild hack, might go away in
+   * future versions)
+   * \param cellId the Cell ID identifying the eNB
+   */
+  virtual void ForceCampedOnEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId) = 0;
+  
+  /** 
+   * Tell the RRC to go into Connected Mode
+   * 
+   * \param params the parameters
+   */
+  virtual void Connect (void) = 0;
+
+  /** 
+   * Send a data packet
+   * 
+   * \param packet the packet
+   * \param drbId the EPS bearer ID
+   * \return true if successful, false otherwise
+   */
+  virtual void SendData (Ptr<Packet> packet, uint8_t bid) = 0;
+
+};
+  
+
+/**
+ * This class implements the Access Stratum (AS) Service Access Point
+ * (SAP), i.e., the interface between the EpcUeNas and the LteEnbRrc
+ * and the EpcEnbApplication. In particular, this class implements the 
+ * User part of the SAP, i.e., the methods exported by the
+ * EpcUeNas and called by the LteEnbRrc.
+ * 
+ */
+class LteAsSapUser
+{
+public:
+  virtual ~LteAsSapUser ();
+  
+  /** 
+   * Notify the NAS that RRC Connection Establishment was successful
+   * 
+   */
+  virtual void NotifyConnectionSuccessful () = 0;
+
+  /** 
+   * Notify the NAS that RRC Connection Establishment failed
+   * 
+   */
+  virtual void NotifyConnectionFailed () = 0;
+
+
+  /** 
+   * receive a data packet
+   * 
+   * \param packet the packet
+   */
+  virtual void RecvData (Ptr<Packet> packet) = 0;
+  
+};
+  
+
+
+
+/**
+ * Template for the implementation of the LteAsSapProvider as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberLteAsSapProvider : public LteAsSapProvider
+{
+public:
+  MemberLteAsSapProvider (C* owner);
+
+  // inherited from LteAsSapProvider
+  virtual void Connect (void);
+  virtual void ForceCampedOnEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId);
+  virtual void SendData (Ptr<Packet> packet, uint8_t bid);
+
+private:
+  MemberLteAsSapProvider ();
+  C* m_owner;
+};
+
+template <class C>
+MemberLteAsSapProvider<C>::MemberLteAsSapProvider (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberLteAsSapProvider<C>::MemberLteAsSapProvider ()
+{
+}
+
+template <class C>
+void 
+MemberLteAsSapProvider<C>::ForceCampedOnEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId)
+{
+  m_owner->DoForceCampedOnEnb (enbDevice, cellId);
+}
+
+
+template <class C>
+void 
+MemberLteAsSapProvider<C>::Connect ()
+{
+  m_owner->DoConnect ();
+}
+
+template <class C>
+void
+MemberLteAsSapProvider<C>::SendData (Ptr<Packet> packet, uint8_t bid)
+{
+  m_owner->DoSendData (packet, bid);
+}
+
+
+/**
+ * Template for the implementation of the LteAsSapUser as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberLteAsSapUser : public LteAsSapUser
+{
+public:
+  MemberLteAsSapUser (C* owner);
+
+  // inherited from LteAsSapUser
+  virtual void NotifyConnectionSuccessful ();
+  virtual void NotifyConnectionFailed ();
+  virtual void RecvData (Ptr<Packet> packet);
+
+private:
+  MemberLteAsSapUser ();
+  C* m_owner;
+};
+
+template <class C>
+MemberLteAsSapUser<C>::MemberLteAsSapUser (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberLteAsSapUser<C>::MemberLteAsSapUser ()
+{
+}
+
+template <class C>
+void 
+MemberLteAsSapUser<C>::NotifyConnectionSuccessful ()
+{
+  m_owner->DoNotifyConnectionSuccessful ();
+}
+
+template <class C>
+void 
+MemberLteAsSapUser<C>::NotifyConnectionFailed ()
+{
+  m_owner->DoNotifyConnectionFailed ();
+}
+
+template <class C>
+void 
+MemberLteAsSapUser<C>::RecvData (Ptr<Packet> packet)
+{
+  m_owner->DoRecvData (packet);
+}
+
+
+} // namespace ns3
+
+#endif // LTE_AS_SAP_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-enb-cphy-sap.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,33 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/lte-enb-cphy-sap.h"
+
+namespace ns3 {
+
+LteEnbCphySapProvider::~LteEnbCphySapProvider ()
+{
+}
+
+LteEnbCphySapUser::~LteEnbCphySapUser ()
+{
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-enb-cphy-sap.h	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,214 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>,
+ *         Marco Miozzo <mmiozzo@cttc.es>
+ */
+
+#ifndef LTE_ENB_CPHY_SAP_H
+#define LTE_ENB_CPHY_SAP_H
+
+#include <stdint.h>
+#include <ns3/ptr.h>
+
+namespace ns3 {
+
+class LteEnbNetDevice;
+
+/**
+ * Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes
+ *
+ * This is the PHY SAP Provider, i.e., the part of the SAP that contains
+ * the PHY methods called by the MAC
+ */
+class LteEnbCphySapProvider
+{
+public:
+
+  /** 
+   * destructor
+   */
+  virtual ~LteEnbCphySapProvider ();
+
+  /** 
+   * 
+   * 
+   * \param cellId the Cell Identifier
+   */
+  virtual void SetCellId (uint16_t cellId) = 0;
+
+  /**
+   * \param ulBandwidth the UL bandwidth in PRBs
+   * \param dlBandwidth the DL bandwidth in PRBs
+   */
+  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth) = 0;
+
+  /**
+   * \param ulEarfcn the UL EARFCN
+   * \param dlEarfcn the DL EARFCN
+   */
+  virtual void SetEarfcn (uint16_t ulEarfcn, uint16_t dlEarfcn) = 0;
+
+
+  /** 
+   * Add a new UE to the cell
+   * 
+   * \param imsi the unique UE id
+   * \param rnti the UE id relative to this cell
+   */
+  virtual void AddUe (uint64_t imsi, uint16_t rnti) = 0;
+
+  
+  /**
+  * \param rnti the RNTI of the user
+  * \param txMode the transmissionMode of the user
+  */
+  virtual void SetTransmissionMode (uint16_t  rnti, uint8_t txMode) = 0;
+
+};
+
+
+/**
+ * Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes
+ *
+ * This is the CPHY SAP User, i.e., the part of the SAP that contains the RRC
+ * methods called by the PHY
+*/
+class LteEnbCphySapUser
+{
+public:
+  
+  /** 
+   * destructor
+   */
+  virtual ~LteEnbCphySapUser ();
+
+};
+
+
+/**
+ * Template for the implementation of the LteEnbCphySapProvider as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberLteEnbCphySapProvider : public LteEnbCphySapProvider
+{
+public:
+  MemberLteEnbCphySapProvider (C* owner);
+
+  // inherited from LteEnbCphySapProvider
+  virtual void SetCellId (uint16_t cellId);
+  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
+  virtual void SetEarfcn (uint16_t ulEarfcn, uint16_t dlEarfcn);
+  virtual void AddUe (uint64_t imsi, uint16_t rnti);
+  virtual void SetTransmissionMode (uint16_t  rnti, uint8_t txMode);
+
+private:
+  MemberLteEnbCphySapProvider ();
+  C* m_owner;
+};
+
+template <class C>
+MemberLteEnbCphySapProvider<C>::MemberLteEnbCphySapProvider (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberLteEnbCphySapProvider<C>::MemberLteEnbCphySapProvider ()
+{
+}
+
+template <class C>
+void 
+MemberLteEnbCphySapProvider<C>::SetCellId (uint16_t cellId)
+{
+  m_owner->DoSetCellId (cellId);
+}
+
+
+template <class C>
+void 
+MemberLteEnbCphySapProvider<C>::SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
+{
+  m_owner->DoSetBandwidth (ulBandwidth, dlBandwidth);
+}
+
+template <class C>
+void 
+MemberLteEnbCphySapProvider<C>::SetEarfcn (uint16_t ulEarfcn, uint16_t dlEarfcn)
+{
+  m_owner->DoSetEarfcn (ulEarfcn, dlEarfcn);
+}
+
+template <class C>
+void 
+MemberLteEnbCphySapProvider<C>::AddUe (uint64_t imsi, uint16_t rnti)
+{
+  m_owner->DoAddUe (imsi, rnti);
+}
+
+
+template <class C>
+void 
+MemberLteEnbCphySapProvider<C>::SetTransmissionMode (uint16_t  rnti, uint8_t txMode)
+{
+  m_owner->DoSetTransmissionMode (rnti, txMode);
+}
+
+
+
+
+/**
+ * Template for the implementation of the LteEnbCphySapUser as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberLteEnbCphySapUser : public LteEnbCphySapUser
+{
+public:
+  MemberLteEnbCphySapUser (C* owner);
+
+  // methods inherited from LteEnbCphySapUser go here
+
+private:
+  MemberLteEnbCphySapUser ();
+  C* m_owner;
+};
+
+template <class C>
+MemberLteEnbCphySapUser<C>::MemberLteEnbCphySapUser (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberLteEnbCphySapUser<C>::MemberLteEnbCphySapUser ()
+{
+}
+
+
+
+
+
+
+} // namespace ns3
+
+
+#endif // LTE_ENB_CPHY_SAP_H
--- a/src/lte/model/lte-enb-mac.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-enb-mac.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -871,8 +871,6 @@
 LteEnbMac::DoRrcUpdateConfigurationReq (FfMacCschedSapProvider::CschedUeConfigReqParameters params)
 {
   NS_LOG_FUNCTION (this);
-  // propagates to PHY layer
-  m_enbPhySapProvider->SetTransmissionMode (params.m_rnti, params.m_transmissionMode);
   // propagates to scheduler
   FfMacCschedSapProvider::CschedUeConfigReqParameters req;
   req.m_rnti = params.m_rnti;
--- a/src/lte/model/lte-enb-net-device.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-enb-net-device.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -276,13 +276,7 @@
 {
   NS_LOG_FUNCTION (this);
 
-  m_rrc->ConfigureCell (m_ulBandwidth, m_dlBandwidth);
-
-  // Configuring directly for now, but ideally we should use the PHY
-  // SAP instead. Probably should handle this through the RRC.
-  m_phy->DoSetBandwidth (m_ulBandwidth, m_dlBandwidth);
-  m_phy->DoSetEarfcn (m_dlEarfcn, m_ulEarfcn);
-  m_phy->DoSetCellId (m_cellId);
+  m_rrc->ConfigureCell (m_ulBandwidth, m_dlBandwidth, m_ulEarfcn, m_dlEarfcn, m_cellId);
 
 }
 
--- a/src/lte/model/lte-enb-phy-sap.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-enb-phy-sap.h	Mon Jul 02 18:25:11 2012 +0200
@@ -49,25 +49,6 @@
   virtual void SendMacPdu (Ptr<Packet> p) = 0;
 
   /**
-   * \param ulBandwidth the UL bandwidth in RB
-   * \param dlBandwidth the DL bandwidth in RB
-   */
-  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth) = 0;
-  
-  /**
-  * \param rnti the RNTI of the user
-  * \param txMode the transmissionMode of the user
-  */
-  virtual void SetTransmissionMode (uint16_t  rnti, uint8_t txMode) = 0;
-
-  /** 
-   * 
-   * 
-   * \param cellId the Cell Identifier
-   */
-  virtual void SetCellId (uint16_t cellId) = 0;
-
-  /**
    * \brief Send SendIdealControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel
    * \param msg the Ideal Control Message to send
    */
--- a/src/lte/model/lte-enb-phy.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-enb-phy.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -28,6 +28,7 @@
 
 
 #include "lte-enb-phy.h"
+#include "lte-ue-phy.h"
 #include "lte-net-device.h"
 #include "lte-spectrum-value-helper.h"
 #include "ideal-control-messages.h"
@@ -35,6 +36,10 @@
 #include "lte-enb-mac.h"
 #include <ns3/lte-common.h>
 
+// WILD HACK for the inizialization of direct eNB-UE ctrl messaging
+#include <ns3/node-list.h>
+#include <ns3/node.h>
+#include <ns3/lte-ue-net-device.h>
 
 NS_LOG_COMPONENT_DEFINE ("LteEnbPhy");
 
@@ -124,10 +129,13 @@
 
 LteEnbPhy::LteEnbPhy (Ptr<LteSpectrumPhy> dlPhy, Ptr<LteSpectrumPhy> ulPhy)
   : LtePhy (dlPhy, ulPhy),
+    m_enbPhySapUser (0),
+    m_enbCphySapUser (0),
     m_nrFrames (0),
     m_nrSubFrames (0)
 {
   m_enbPhySapProvider = new EnbMemberLteEnbPhySapProvider (this);
+  m_enbCphySapProvider = new MemberLteEnbCphySapProvider<LteEnbPhy> (this);
   Simulator::ScheduleNow (&LteEnbPhy::StartFrame, this);
 }
 
@@ -176,6 +184,7 @@
   NS_LOG_FUNCTION (this);
   m_ueAttached.clear ();
   delete m_enbPhySapProvider;
+  delete m_enbCphySapProvider;
   LtePhy::DoDispose ();
 }
 
@@ -202,6 +211,20 @@
 }
 
 void
+LteEnbPhy::SetLteEnbCphySapUser (LteEnbCphySapUser* s)
+{
+  NS_LOG_FUNCTION (this);
+  m_enbCphySapUser = s;
+}
+
+LteEnbCphySapProvider*
+LteEnbPhy::GetLteEnbCphySapProvider ()
+{
+  NS_LOG_FUNCTION (this);
+  return (m_enbCphySapProvider);
+}
+
+void
 LteEnbPhy::SetTxPower (double pow)
 {
   NS_LOG_FUNCTION (this << pow);
@@ -232,6 +255,7 @@
 void
 LteEnbPhy::SetMacChDelay (uint8_t delay)
 {
+  NS_LOG_FUNCTION (this);
   m_macChTtiDelay = delay;
   for (int i = 0; i < m_macChTtiDelay; i++)
     {
@@ -255,9 +279,12 @@
   return (m_macChTtiDelay);
 }
 
+
+
 bool
 LteEnbPhy::AddUePhy (uint16_t rnti, Ptr<LteUePhy> phy)
 {
+  NS_LOG_FUNCTION (this);
   std::map <uint16_t, Ptr<LteUePhy> >::iterator it;
   it = m_ueAttached.find (rnti);
   if (it == m_ueAttached.end ())
@@ -275,6 +302,7 @@
 bool
 LteEnbPhy::DeleteUePhy (uint16_t rnti)
 {
+  NS_LOG_FUNCTION (this);
   std::map <uint16_t, Ptr<LteUePhy> >::iterator it;
   it = m_ueAttached.find (rnti);
   if (it == m_ueAttached.end ())
@@ -544,6 +572,77 @@
 	
 }
 
+
+void
+LteEnbPhy::DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
+{
+  NS_LOG_FUNCTION (this << (uint32_t) ulBandwidth << (uint32_t) dlBandwidth);
+  m_ulBandwidth = ulBandwidth;
+  m_dlBandwidth = dlBandwidth;
+
+  int Type0AllocationRbg[4] = {
+    10,     // RGB size 1
+    26,     // RGB size 2
+    63,     // RGB size 3
+    110     // RGB size 4
+  };  // see table 7.1.6.1-1 of 36.213
+  for (int i = 0; i < 4; i++)
+    {
+      if (dlBandwidth < Type0AllocationRbg[i])
+        {
+          m_rbgSize = i + 1;
+          break;
+        }
+    }
+}
+
+void 
+LteEnbPhy::DoSetEarfcn (uint16_t ulEarfcn, uint16_t dlEarfcn)
+{
+  NS_LOG_FUNCTION (this << ulEarfcn << dlEarfcn);
+  m_ulEarfcn = ulEarfcn;
+  m_dlEarfcn = dlEarfcn;
+}
+
+
+void 
+LteEnbPhy::DoAddUe (uint64_t imsi, uint16_t rnti)
+{
+  NS_LOG_FUNCTION (this << imsi << rnti);
+  // since for now ctrl messages are still sent directly to the UePhy
+  // without passing to the channel, we need to get a pointer to the
+  // UePhy. We do so by walking the whole UE list. This code will
+  // eventually go away when a real control channel is implemented.
+
+  Ptr<LteUePhy> uePhy;
+  NodeList::Iterator listEnd = NodeList::End ();
+  bool found = false;
+  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+    {
+      Ptr<Node> node = *i;
+      int nDevs = node->GetNDevices ();
+      for (int j = 0; j < nDevs; j++)
+        {
+          Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
+          if (!ueDev)
+            {
+              continue;
+            }
+          else
+            {
+              if (ueDev->GetImsi () == imsi)
+                {
+                  found = true;
+                  uePhy = ueDev->GetPhy ();
+                }
+            }
+        }
+    }
+  NS_ASSERT_MSG (found , " Unable to find UE with IMSI =" << imsi);
+  bool success = AddUePhy (rnti, uePhy);
+  NS_ASSERT_MSG (success, "AddUePhy() failed");
+}
+
 void
 LteEnbPhy::DoSetTransmissionMode (uint16_t  rnti, uint8_t txMode)
 {
--- a/src/lte/model/lte-enb-phy.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-enb-phy.h	Mon Jul 02 18:25:11 2012 +0200
@@ -24,14 +24,16 @@
 
 
 #include "lte-phy.h"
+#include <ns3/ideal-control-messages.h>
 #include <ns3/lte-enb-phy-sap.h>
+#include <ns3/lte-enb-cphy-sap.h>
 #include <map>
-#include <ns3/lte-ue-phy.h>
 
 namespace ns3 {
 
 class PacketBurst;
 class LteNetDevice;
+class LteUePhy;
 
 /**
  * \ingroup lte
@@ -39,9 +41,9 @@
  */
 class LteEnbPhy : public LtePhy
 {
-
   friend class EnbMemberLteEnbPhySapProvider;
-
+  friend class MemberLteEnbCphySapProvider<LteEnbPhy>;
+  
 public:
   /**
    * @warning the default constructor should not be used
@@ -76,6 +78,18 @@
   void SetLteEnbPhySapUser (LteEnbPhySapUser* s);
 
   /**
+   * \brief Get the CPHY SAP provider
+   * \return a pointer to the SAP Provider
+   */
+  LteEnbCphySapProvider* GetLteEnbCphySapProvider ();
+
+  /**
+  * \brief Set the CPHY SAP User
+  * \param s a pointer to the SAP user
+  */
+  void SetLteEnbCphySapUser (LteEnbCphySapUser* s);
+
+  /**
    * \param pw the transmission power in dBm
    */
   void SetTxPower (double pow);
@@ -150,11 +164,6 @@
 
   void DoSendIdealControlMessage (Ptr<IdealControlMessage> msg);
 
-  bool AddUePhy (uint16_t rnti, Ptr<LteUePhy> phy);
-
-  bool DeleteUePhy (uint16_t rnti);
-  
-  virtual void DoSetTransmissionMode (uint16_t  rnti, uint8_t txMode);
   
   /**
   * \param m the UL-CQI to be queued
@@ -194,6 +203,19 @@
 
 
 private:
+
+  // LteEnbCphySapProvider forwarded methods
+  void DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
+  void DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn);
+  void DoAddUe (uint64_t imsi, uint16_t rnti);  
+  void DoSetTransmissionMode (uint16_t  rnti, uint8_t txMode);
+  
+
+  bool AddUePhy (uint16_t rnti, Ptr<LteUePhy> phy);
+
+  bool DeleteUePhy (uint16_t rnti);
+
+
   std::map <uint16_t, Ptr<LteUePhy> > m_ueAttached;
   
   std::vector< std::list<UlDciIdealControlMessage> > m_ulDciQueue; // for storing info on future receptions
@@ -201,6 +223,9 @@
   LteEnbPhySapProvider* m_enbPhySapProvider;
   LteEnbPhySapUser* m_enbPhySapUser;
 
+  LteEnbCphySapProvider* m_enbCphySapProvider;
+  LteEnbCphySapUser* m_enbCphySapUser;
+
   uint32_t m_nrFrames;
   uint32_t m_nrSubFrames;
   
--- a/src/lte/model/lte-enb-rrc.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-enb-rrc.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -32,8 +32,12 @@
 #include "lte-pdcp-sap.h"
 #include "lte-radio-bearer-info.h"
 #include "lte-radio-bearer-tag.h"
-#include "ns3/object-map.h"
-#include <ns3/ff-mac-csched-sap.h>
+#include "ff-mac-csched-sap.h"
+#include "epc-enb-s1-sap.h"
+
+#include "lte-rlc.h"
+#include "lte-rlc-um.h"
+#include "lte-rlc-am.h"
 
 // WILD HACK for UE-RRC direct communications
 #include <ns3/node-list.h>
@@ -84,35 +88,6 @@
 }
 
 
-////////////////////////////////
-// PDCP SAP Forwarder
-////////////////////////////////
-
-// not needed any more if the template works
-
-// class EnbRrcMemberLtePdcpSapUser : public LtePdcpSapUser
-// {
-// public:
-//   MemberLtePdcpSapUser (LteEnbRrc* rrc);
-//   virtual void ReceiveRrcPdu (Ptr<Packet> p);
-// private:
-//   LteEnbRrc* m_rrc;
-// };
-
-
-// EnbRrcMemberLtePdcpSapUser::EnbRrcMemberLtePdcpSapUser (LteEnbRrc* rrc)
-//   : m_rrc (rrc)
-// {
-// }
-
-// void EnbRrcMemberLtePdcpSapUser::ReceiveRrcPdu (Ptr<Packet> p)
-// {
-//   m_rrc->DoReceiveRrcPdu (p);
-// }
-
-
-
-
 ///////////////////////////////////////////
 // UeInfo 
 ///////////////////////////////////////////
@@ -212,12 +187,16 @@
   : m_cmacSapProvider (0),
     m_ffMacSchedSapProvider (0),
     m_macSapProvider (0),
+    m_s1SapProvider (0),
+    m_cphySapProvider (0),
     m_configured (false),
     m_lastAllocatedRnti (0)
 {
   NS_LOG_FUNCTION (this);
   m_cmacSapUser = new EnbRrcMemberLteEnbCmacSapUser (this);
   m_pdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteEnbRrc> (this);
+  m_s1SapUser = new MemberEpcEnbS1SapUser<LteEnbRrc> (this);
+  m_cphySapUser = new MemberLteEnbCphySapUser<LteEnbRrc> (this);
 }
 
 
@@ -233,6 +212,8 @@
   NS_LOG_FUNCTION (this);
   delete m_cmacSapUser;
   delete m_pdcpSapUser;
+  delete m_s1SapUser;
+  delete m_cphySapUser;
 }
 
 TypeId
@@ -251,7 +232,14 @@
                   UintegerValue (0),  // default tx-mode
                   MakeUintegerAccessor (&LteEnbRrc::m_defaultTransmissionMode),
                   MakeUintegerChecker<uint8_t> ())
-             
+    .AddAttribute ("EpsBearerToRlcMapping", 
+                   "Specify which type of RLC will be used for each type of EPS bearer. ",
+                   EnumValue (RLC_SM_ALWAYS),
+                   MakeEnumAccessor (&LteEnbRrc::m_epsBearerToRlcMapping),
+                   MakeEnumChecker (RLC_SM_ALWAYS, "RlcSmAlways",
+                                    RLC_UM_ALWAYS, "RlcUmAlways",
+                                    RLC_AM_ALWAYS, "RlcAmAlways",
+                                    PER_BASED,     "PacketErrorRateBased"))             
   ;
   return tid;
 }
@@ -281,6 +269,19 @@
 }
 
 
+void
+LteEnbRrc::SetLteEnbCphySapProvider (LteEnbCphySapProvider * s)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_cphySapProvider = s;
+}
+
+LteEnbCphySapUser*
+LteEnbRrc::GetLteEnbCphySapUser ()
+{
+  NS_LOG_FUNCTION (this);
+  return m_cphySapUser;
+}
 
 void
 LteEnbRrc::SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s)
@@ -311,6 +312,19 @@
   m_macSapProvider = s;
 }
 
+void 
+LteEnbRrc::SetS1SapProvider (EpcEnbS1SapProvider * s)
+{
+  m_s1SapProvider = s;
+}
+
+  
+EpcEnbS1SapUser* 
+LteEnbRrc::GetS1SapUser ()
+{
+  return m_s1SapUser;
+}
+
 LtePdcpSapProvider* 
 LteEnbRrc::GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid)
 {
@@ -318,11 +332,14 @@
 }
 
 void
-LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth)
+LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth, uint16_t ulEarfcn, uint16_t dlEarfcn, uint16_t cellId)
 {
   NS_LOG_FUNCTION (this);
   NS_ASSERT (!m_configured);
   m_cmacSapProvider->ConfigureMac (ulBandwidth, dlBandwidth);
+  m_cphySapProvider->SetBandwidth (ulBandwidth, dlBandwidth);
+  m_cphySapProvider->SetEarfcn (ulEarfcn, dlEarfcn);
+  m_cphySapProvider->SetCellId (cellId);
   m_configured = true;
 }
 
@@ -332,8 +349,10 @@
   NS_LOG_FUNCTION (this << imsi);
   // no Call Admission Control for now
   uint16_t rnti = CreateUeInfo (imsi); // side effect: create UeInfo for this UE
+  m_imsiRntiMap[imsi] = rnti; // side effect: add entry if not present
   NS_ASSERT_MSG (rnti != 0, "CreateUeInfo returned RNTI==0");
   m_cmacSapProvider->AddUe (rnti);
+  m_cphySapProvider->AddUe (imsi, rnti);
   return rnti;
 }
 
@@ -342,13 +361,78 @@
 {
   NS_LOG_FUNCTION (this << (uint32_t) rnti);
   RemoveUeInfo (rnti);
+  m_imsiRntiMap.erase (rnti);
   NS_FATAL_ERROR ("missing RemoveUe method in CMAC SAP");
 }
 
+TypeId
+LteEnbRrc::GetRlcType (EpsBearer bearer)
+{
+  switch (m_epsBearerToRlcMapping)
+    {
+    case RLC_SM_ALWAYS:
+      return LteRlcSm::GetTypeId ();
+      break;
+
+    case  RLC_UM_ALWAYS:
+      return LteRlcUm::GetTypeId ();
+      break;
+
+    case RLC_AM_ALWAYS:
+      return LteRlcAm::GetTypeId ();
+      break;
+
+    case PER_BASED:
+      if (bearer.GetPacketErrorLossRate () > 1.0e-5)
+        {
+          return LteRlcUm::GetTypeId ();
+        }
+      else
+        {
+          return LteRlcAm::GetTypeId ();
+        }
+      break;
+
+    default:
+      return LteRlcSm::GetTypeId ();
+      break;
+    }
+}
+
+
+void 
+LteEnbRrc::DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters request)
+{
+  EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters response;
+  std::map<uint64_t, uint16_t>::iterator it = m_imsiRntiMap.find (request.imsi);
+  if (it == m_imsiRntiMap.end ())
+    {
+      NS_LOG_ERROR ("unknown IMSI");
+      response.success = false;
+      if (m_s1SapProvider)
+        {
+          m_s1SapProvider->DataRadioBearerSetupResponse (response);      
+        }
+    }
+  else
+    {
+      response.rnti = it->second;
+      response.lcid = SetupRadioBearer (response.rnti, request.bearer);      
+      response.success = (response.lcid > 0);
+      response.teid = request.teid;
+      if (m_s1SapProvider)
+        {          
+          m_s1SapProvider->DataRadioBearerSetupResponse (response);
+        }
+    }
+}
+
 uint8_t
-LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId)
+LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer)
 {
   NS_LOG_FUNCTION (this << (uint32_t) rnti);
+
+  TypeId rlcTypeId = GetRlcType (bearer);
   Ptr<UeInfo> ueInfo = GetUeInfo (rnti);
 
   // create RLC instance
@@ -362,6 +446,11 @@
   Ptr<LteRadioBearerInfo> rbInfo = CreateObject<LteRadioBearerInfo> ();
   rbInfo->m_rlc = rlc;
   uint8_t lcid = ueInfo->AddRadioBearer (rbInfo);
+  if (lcid == 0)
+    {
+      NS_LOG_WARN ("cannot setup radio bearer");
+      return 0;
+    }
   rlc->SetLcId (lcid);
 
   // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
@@ -388,6 +477,8 @@
   lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
   lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
   m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
+
+  GetUeRrcByRnti (rnti)->SetupRadioBearer (bearer, rlcTypeId, lcid);
   
   // Transmission mode settings
   LteUeConfig_t ueConfig;
@@ -401,7 +492,7 @@
 void
 LteEnbRrc::ReleaseRadioBearer (uint16_t rnti, uint8_t lcId)
 {
-  NS_LOG_FUNCTION (this << (uint32_t) rnti);
+  NS_LOG_FUNCTION (this << (uint32_t) rnti << (uint32_t) lcId);
   Ptr<UeInfo> ueInfo = GetUeInfo (rnti);
   ueInfo->RemoveRadioBearer (lcId);
 }
@@ -507,44 +598,59 @@
   NS_LOG_FUNCTION (this);
   // up tp now only for TxMode change
   // update the peer UE-RRC on the change
+  Ptr<LteUeRrc> ueRrc = GetUeRrcByRnti (params.m_rnti);
+  ueRrc->DoRrcConfigurationUpdateInd (params);
+  
+  // configure MAC (and scheduler)
+  FfMacCschedSapProvider::CschedUeConfigReqParameters req;
+  req.m_rnti = params.m_rnti;
+  req.m_transmissionMode = params.m_transmissionMode;
+  m_cmacSapProvider->RrcUpdateConfigurationReq (req);
+
+  // configure PHY
+  m_cphySapProvider->SetTransmissionMode (params.m_rnti, params.m_transmissionMode);
+}
+
+
+Ptr<LteUeRrc> 
+LteEnbRrc::GetUeRrcByImsi (uint64_t imsi)
+{
+  NS_LOG_FUNCTION (this);
+
   NodeList::Iterator listEnd = NodeList::End ();
-  bool done = false;
+  bool found = false;
   for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
     {
       Ptr<Node> node = *i;
       int nDevs = node->GetNDevices ();
       for (int j = 0; j < nDevs; j++)
         {
-          Ptr<LteUeNetDevice> uedev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
-          if (!uedev)
+          Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
+          if (!ueDev)
             {
               continue;
             }
           else
             {
-              Ptr<LteUeRrc> ueRrc = uedev->GetRrc ();
-              if (ueRrc->GetRnti () == params.m_rnti)
+              if (ueDev->GetImsi () == imsi)
                 {
-                  ueRrc->DoRrcConfigurationUpdateInd (params);
-                  done = true;
-                }
-              else
-                {
-                  continue;
+                  found = true;
+                  return ueDev->GetRrc ();
                 }
             }
         }
     }
-  NS_ASSERT_MSG (done , " Unable to find peer UE-RRC, RNTI " << params.m_rnti);
-  // answer to MAC (and scheduler)
-  FfMacCschedSapProvider::CschedUeConfigReqParameters req;
-  req.m_rnti = params.m_rnti;
-  req.m_transmissionMode = params.m_transmissionMode;
-  m_cmacSapProvider->RrcUpdateConfigurationReq (req);
-  
+  NS_ASSERT_MSG (found , " Unable to find UE with IMSI =" << imsi);
+  return 0;
 }
 
 
+Ptr<LteUeRrc> 
+LteEnbRrc::GetUeRrcByRnti (uint16_t rnti)
+{
+  uint64_t imsi = GetUeInfo (rnti)->GetImsi ();
+  return GetUeRrcByImsi (imsi);
+}
 
 
 } // namespace ns3
--- a/src/lte/model/lte-enb-rrc.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-enb-rrc.h	Mon Jul 02 18:25:11 2012 +0200
@@ -26,6 +26,8 @@
 #include <ns3/lte-enb-cmac-sap.h>
 #include <ns3/ff-mac-common.h>
 #include <ns3/lte-pdcp-sap.h>
+#include <ns3/epc-enb-s1-sap.h>
+#include <ns3/lte-enb-cphy-sap.h>
 
 #include <map>
 
@@ -36,13 +38,15 @@
 class LteRadioBearerInfo;
 class LtePdcpSapUser;
 class LtePdcpSapProvider;
+class EpcEnbS1SapUser;
+class EpcEnbS1SapProvider;
+class LteUeRrc;
 
 
 /**
  * Manages all the radio bearer information possessed by the ENB RRC for a single UE
  *
  */
-
 class UeInfo : public Object
 {
 public:
@@ -88,14 +92,16 @@
 
 
 /**
- *
- *
+ * \ingroup lte
+ * 
+ * The LTE Radio Resource Control entity at the eNB
  */
 class LteEnbRrc : public Object
 {
 
   friend class EnbRrcMemberLteEnbCmacSapUser;
   friend class LtePdcpSpecificLtePdcpSapUser<LteEnbRrc>;
+  friend class MemberEpcEnbS1SapUser<LteEnbRrc>;
 
 public:
   /**
@@ -149,15 +155,49 @@
   void SetLteMacSapProvider (LteMacSapProvider* s);
 
 
+  /** 
+   * Set the S1 SAP Provider
+   * 
+   * \param s the S1 SAP Provider
+   */
+  void SetS1SapProvider (EpcEnbS1SapProvider * s);
+
+  /** 
+   * 
+   * \return the S1 SAP user
+   */
+  EpcEnbS1SapUser* GetS1SapUser ();
+
+
+  /**
+   * set the CPHY SAP this RRC should use to interact with the PHY
+   *
+   * \param s the CPHY SAP Provider
+   */
+  void SetLteEnbCphySapProvider (LteEnbCphySapProvider * s);
+
+  /**
+   *
+   *
+   * \return s the CPHY SAP User interface offered to the PHY by this RRC
+   */
+  LteEnbCphySapUser* GetLteEnbCphySapUser ();
+
 
   /**
    * configure cell-specific parameters
    *
    * \param ulBandwidth the uplink bandwdith in number of RB
    * \param dlBandwidth the downlink bandwidth in number of RB
+   * \param ulEarfcn the UL EARFCN
+   * \param dlEarfcn the DL EARFCN
+   * \param cellId the ID of the cell
    */
   void ConfigureCell (uint8_t ulBandwidth,
-                      uint8_t dlBandwidth);
+                      uint8_t dlBandwidth,
+                      uint16_t ulEarfcn, 
+                      uint16_t dlEarfcn,
+                      uint16_t cellId);
 
   /**
    * Add a new UE to the cell
@@ -179,16 +219,24 @@
   void SetUeMap (std::map<uint16_t,Ptr<UeInfo> > ueMap);
   std::map<uint16_t,Ptr<UeInfo> > GetUeMap (void) const;
 
+  /** 
+   * 
+   * \param bearer the specification of an EPS bearer
+   * 
+   * \return the type of RLC that is to be created for the given EPS bearer
+   */
+  TypeId GetRlcType (EpsBearer bearer);
+
+
   /**
    * Setup a new radio bearer for the given user
    *
    * \param rnti the RNTI of the user
    * \param bearer the characteristics of the bearer to be activated
-   * \param rlcTypeId the TypeId identifying the type of RLC to be used for this bearer.
    *
    * \return the logical channel identifier of the radio bearer for the considered user
    */
-  uint8_t SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId);
+  uint8_t SetupRadioBearer (uint16_t rnti, EpsBearer bearer);
 
 
   /**
@@ -217,21 +265,40 @@
    * \param cb 
    */
   void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
-  
-  
+
+  /**
+   * Identifies how EPS Bearer parameters are mapped to different RLC types
+   * 
+   */
+  enum LteEpsBearerToRlcMapping_t {RLC_SM_ALWAYS = 1,
+                                   RLC_UM_ALWAYS = 2,
+                                   RLC_AM_ALWAYS = 3,
+                                   PER_BASED = 4};
 private:
 
+
+  LtePdcpSapProvider* GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid);
+
+  // PDCP SAP methods
   void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
+
+  // CMAC SAP methods
   void DoRrcConfigurationUpdateInd (LteUeConfig_t params);
-  
   void DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
-  LtePdcpSapProvider* GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid);
+
+  // S1 SAP methods
+  void DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params);
+
 
   // management of multiple UE info instances
   uint16_t CreateUeInfo (uint64_t imsi);
   Ptr<UeInfo> GetUeInfo (uint16_t rnti);
   void RemoveUeInfo (uint16_t rnti);
 
+  // methods used to talk to UE RRC directly in absence of real RRC protocol
+  Ptr<LteUeRrc> GetUeRrcByImsi (uint64_t imsi);
+  Ptr<LteUeRrc> GetUeRrcByRnti (uint16_t rnti);
+
   Callback <void, Ptr<Packet> > m_forwardUpCallback;
 
   LteEnbCmacSapUser* m_cmacSapUser;
@@ -241,13 +308,24 @@
   LteMacSapProvider* m_macSapProvider;
   LtePdcpSapUser* m_pdcpSapUser;
 
+  EpcEnbS1SapProvider* m_s1SapProvider;
+  EpcEnbS1SapUser* m_s1SapUser;
+
+  LteEnbCphySapUser* m_cphySapUser;
+  LteEnbCphySapProvider* m_cphySapProvider;
+
   bool m_configured;
   uint16_t m_lastAllocatedRnti;
 
+  std::map<uint64_t, uint16_t> m_imsiRntiMap;
+
   std::map<uint16_t, Ptr<UeInfo> > m_ueMap;
   
   uint8_t m_defaultTransmissionMode;
 
+  enum LteEpsBearerToRlcMapping_t m_epsBearerToRlcMapping;
+
+
 };
 
 
--- a/src/lte/model/lte-phy.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-phy.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -187,35 +187,6 @@
   return m_tti;
 }
 
-void
-LtePhy::DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
-{
-  m_ulBandwidth = ulBandwidth;
-  m_dlBandwidth = dlBandwidth;
-
-  int Type0AllocationRbg[4] = {
-    10,     // RGB size 1
-    26,     // RGB size 2
-    63,     // RGB size 3
-    110     // RGB size 4
-  };  // see table 7.1.6.1-1 of 36.213
-  for (int i = 0; i < 4; i++)
-    {
-      if (dlBandwidth < Type0AllocationRbg[i])
-        {
-          m_rbgSize = i + 1;
-          break;
-        }
-    }
-}
-
-void 
-LtePhy::DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn)
-{
-  m_dlEarfcn = dlEarfcn;
-  m_ulEarfcn = ulEarfcn;
-}
-
 uint8_t
 LtePhy::GetRbgSize (void) const
 {
@@ -258,6 +229,7 @@
 std::list<Ptr<IdealControlMessage> >
 LtePhy::GetControlMessages (void)
 {
+  NS_LOG_FUNCTION (this);
   if (m_controlMessagesQueue.at (0).size () > 0)
     {
       std::list<Ptr<IdealControlMessage> > ret = m_controlMessagesQueue.at (0);
--- a/src/lte/model/lte-phy.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-phy.h	Mon Jul 02 18:25:11 2012 +0200
@@ -169,19 +169,6 @@
    */
   double GetTti (void) const;
 
-  /**
-  * \param ulBandwidth the UL bandwidth in RB
-  * \param dlBandwidth the DL bandwidth in RB
-  */
-  void DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
-
-  /**
-   *
-   * \param dlEarfcn the carrier frequency (EARFCN) in downlink
-   * \param ulEarfcn the carrier frequency (EARFCN) in downlink
-   */
-  virtual void DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn);
-
   /** 
    * 
    * \param cellId the Cell Identifier
--- a/src/lte/model/lte-rlc-um.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-rlc-um.h	Mon Jul 02 18:25:11 2012 +0200
@@ -22,9 +22,9 @@
 #define LTE_RLC_UM_H
 
 #include "ns3/lte-rlc-sequence-number.h"
-
 #include "ns3/lte-rlc.h"
 
+#include <ns3/event-id.h>
 #include <map>
 
 namespace ns3 {
--- a/src/lte/model/lte-ue-cmac-sap.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-cmac-sap.h	Mon Jul 02 18:25:11 2012 +0200
@@ -52,8 +52,6 @@
 
   virtual void RemoveLc (uint8_t lcId) = 0;
   
-  virtual void RrcUpdateConfigurationReq (LteUeConfig_t params) = 0;
-
 };
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-ue-cphy-sap.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,33 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/lte-ue-cphy-sap.h"
+
+namespace ns3 {
+
+LteUeCphySapProvider::~LteUeCphySapProvider ()
+{
+}
+
+LteUeCphySapUser::~LteUeCphySapUser ()
+{
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-ue-cphy-sap.h	Mon Jul 02 18:25:11 2012 +0200
@@ -0,0 +1,209 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>,
+ *         Marco Miozzo <mmiozzo@cttc.es>
+ */
+
+#ifndef LTE_UE_CPHY_SAP_H
+#define LTE_UE_CPHY_SAP_H
+
+#include <stdint.h>
+#include <ns3/ptr.h>
+
+namespace ns3 {
+
+
+class LteEnbNetDevice;
+
+/**
+ * Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes
+ *
+ * This is the PHY SAP Provider, i.e., the part of the SAP that contains
+ * the PHY methods called by the MAC
+ */
+class LteUeCphySapProvider
+{
+public:
+
+  /** 
+   * destructor
+   */
+  virtual ~LteUeCphySapProvider ();
+
+  /** 
+   * tell the PHY to synchronize with a given eNB for communication purposes
+   * 
+   * \param enbPhy a pointer to the PHY of the eNB (wild hack, might go away in later versions)
+   * \param cellId the ID of the eNB
+   */
+  virtual void SyncronizeWithEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId) = 0;
+  
+  /**
+   *
+   * \param dlEarfcn the carrier frequency (EARFCN) in downlink
+   * \param ulEarfcn the carrier frequency (EARFCN) in downlink
+   */
+  virtual void SetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn) = 0;
+
+  /**
+   * \param ulBandwidth the UL bandwidth in PRBs
+   * \param dlBandwidth the DL bandwidth in PRBs
+   */
+  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth) = 0;
+  
+  /** 
+   * 
+   * \param rnti the cell-specific UE identifier
+   */
+  virtual void SetRnti (uint16_t rnti) = 0;
+
+  /**
+   * \param txMode the transmissionMode of the user
+   */
+  virtual void SetTransmissionMode (uint8_t txMode) = 0;
+
+};
+
+
+/**
+ * Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes
+ *
+ * This is the CPHY SAP User, i.e., the part of the SAP that contains the RRC
+ * methods called by the PHY
+*/
+class LteUeCphySapUser
+{
+public:
+  
+  /** 
+   * destructor
+   */
+  virtual ~LteUeCphySapUser ();
+};
+
+
+
+
+/**
+ * Template for the implementation of the LteUeCphySapProvider as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberLteUeCphySapProvider : public LteUeCphySapProvider
+{
+public:
+  MemberLteUeCphySapProvider (C* owner);
+
+  // inherited from LteUeCphySapProvider
+  virtual void SyncronizeWithEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId);
+  virtual void SetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn);
+  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
+  virtual void SetRnti (uint16_t rnti);
+  virtual void SetTransmissionMode (uint8_t txMode);
+
+private:
+  MemberLteUeCphySapProvider ();
+  C* m_owner;
+};
+
+template <class C>
+MemberLteUeCphySapProvider<C>::MemberLteUeCphySapProvider (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberLteUeCphySapProvider<C>::MemberLteUeCphySapProvider ()
+{
+}
+
+template <class C>
+void 
+MemberLteUeCphySapProvider<C>::SyncronizeWithEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId)
+{
+  m_owner->DoSyncronizeWithEnb (enbDevice, cellId);
+}
+
+template <class C>
+void 
+MemberLteUeCphySapProvider<C>::SetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn)
+{
+  m_owner->DoSetEarfcn (dlEarfcn, ulEarfcn);
+}
+
+template <class C>
+void 
+MemberLteUeCphySapProvider<C>::SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
+{
+  m_owner->DoSetBandwidth (ulBandwidth, dlBandwidth);
+}
+
+template <class C>
+void 
+MemberLteUeCphySapProvider<C>::SetRnti (uint16_t rnti)
+{
+  m_owner->DoSetRnti (rnti);
+}
+
+template <class C>
+void 
+MemberLteUeCphySapProvider<C>::SetTransmissionMode (uint8_t txMode)
+{
+  m_owner->DoSetTransmissionMode (txMode);
+}
+
+
+
+
+/**
+ * Template for the implementation of the LteUeCphySapUser as a member
+ * of an owner class of type C to which all methods are forwarded
+ * 
+ */
+template <class C>
+class MemberLteUeCphySapUser : public LteUeCphySapUser
+{
+public:
+  MemberLteUeCphySapUser (C* owner);
+
+  // methods inherited from LteUeCphySapUser go here
+
+private:
+  MemberLteUeCphySapUser ();
+  C* m_owner;
+};
+
+template <class C>
+MemberLteUeCphySapUser<C>::MemberLteUeCphySapUser (C* owner)
+  : m_owner (owner)
+{
+}
+
+template <class C>
+MemberLteUeCphySapUser<C>::MemberLteUeCphySapUser ()
+{
+}
+
+
+
+
+} // namespace ns3
+
+
+#endif // LTE_UE_CPHY_SAP_H
--- a/src/lte/model/lte-ue-mac.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-mac.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -56,7 +56,6 @@
   virtual void ConfigureUe (uint16_t rnti);
   virtual void AddLc (uint8_t lcId, LteMacSapUser* msu);
   virtual void RemoveLc (uint8_t lcId);
-  virtual void RrcUpdateConfigurationReq (LteUeConfig_t params);
 
 private:
   LteUeMac* m_mac;
@@ -86,13 +85,6 @@
   m_mac->DoRemoveLc (lcid);
 }
 
-void
-UeMemberLteUeCmacSapProvider::RrcUpdateConfigurationReq (LteUeConfig_t params)
-{
-  m_mac->DoRrcUpdateConfigurationReq (params);
-}
-
-
 class UeMemberLteMacSapProvider : public LteMacSapProvider
 {
 public:
@@ -339,14 +331,6 @@
   m_macSapUserMap.erase (lcId);
 }
 
-void
-LteUeMac::DoRrcUpdateConfigurationReq (LteUeConfig_t params)
-{
-  NS_LOG_FUNCTION (this << " txMode " << (uint8_t) params.m_transmissionMode);
-  // forward info to PHY layer
-  m_uePhySapProvider->SetTransmissionMode (params.m_transmissionMode);
-}
-
 
 void
 LteUeMac::DoReceivePhyPdu (Ptr<Packet> p)
--- a/src/lte/model/lte-ue-net-device.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-net-device.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -38,9 +38,11 @@
 #include "ns3/ipv4-header.h"
 #include "ns3/ipv4.h"
 #include "lte-amc.h"
-#include <ns3/lte-ue-phy.h>
+#include "lte-ue-phy.h"
+#include "epc-ue-nas.h"
 #include <ns3/ipv4-l3-protocol.h>
 #include <ns3/log.h>
+#include "epc-tft.h"
 
 NS_LOG_COMPONENT_DEFINE ("LteUeNetDevice");
 
@@ -72,12 +74,11 @@
                    PointerValue (),
                    MakePointerAccessor (&LteUeNetDevice::m_phy),
                    MakePointerChecker <LteUePhy> ())
-/*    .AddAttribute ("Imsi",
+    .AddAttribute ("Imsi",
                    "International Mobile Subscriber Identity assigned to this UE",
-                   TypeId::ATTR_GET,
-                   UintegerValue (0), // not used because the attribute is read-only
-                   MakeUintegerAccessor (&LteUeNetDevice::m_imsi),
-                   MakeUintegerChecker<uint64_t> ())*/
+                   UintegerValue (0), // unused, read-only attribute
+                   MakeUintegerAccessor (&LteUeNetDevice::GetImsi),
+                   MakeUintegerChecker<uint64_t> ())
   ;
 
   return tid;
@@ -91,12 +92,13 @@
 }
 
 
-LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc)
+  LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas)
 {
   NS_LOG_FUNCTION (this);
   m_phy = phy;
   m_mac = mac;
   m_rrc = rrc;
+  m_nas = nas;
   SetNode (node);
   m_imsi = ++m_imsiCounter;
 }
@@ -124,12 +126,15 @@
 LteUeNetDevice::UpdateConfig (void)
 {
   NS_LOG_FUNCTION (this);
+  m_nas->SetImsi (m_imsi);
+  m_rrc->SetImsi (m_imsi);
+  
 }
 
 
 
 Ptr<LteUeMac>
-LteUeNetDevice::GetMac (void)
+LteUeNetDevice::GetMac (void) const
 {
   NS_LOG_FUNCTION (this);
   return m_mac;
@@ -137,7 +142,7 @@
 
 
 Ptr<LteUeRrc>
-LteUeNetDevice::GetRrc (void)
+LteUeNetDevice::GetRrc (void) const
 {
   NS_LOG_FUNCTION (this);
   return m_rrc;
@@ -151,14 +156,25 @@
   return m_phy;
 }
 
+Ptr<EpcUeNas>
+LteUeNetDevice::GetNas (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_nas;
+}
+
+uint64_t
+LteUeNetDevice::GetImsi () const
+{
+  NS_LOG_FUNCTION (this);
+  return m_imsi;
+}
+
 void
 LteUeNetDevice::SetTargetEnb (Ptr<LteEnbNetDevice> enb)
 {
   NS_LOG_FUNCTION (this << enb);
   m_targetEnb = enb;
-
-  // should go through RRC and then through PHY SAP
-  m_phy->DoSetCellId (enb->GetCellId ());
 }
 
 
@@ -169,14 +185,12 @@
   return m_targetEnb;
 }
 
-uint64_t
-LteUeNetDevice::GetImsi ()
+void 
+LteUeNetDevice::ActivateDedicatedEpsBearer (EpsBearer bearer, Ptr<EpcTft> tft)
 {
-  NS_LOG_FUNCTION (this);
-  return m_imsi;
+  m_nas->ActivateEpsBearer (bearer, tft);
 }
 
-
 void 
 LteUeNetDevice::DoStart (void)
 {
@@ -193,7 +207,7 @@
   NS_LOG_FUNCTION (this << dest << protocolNumber);
   NS_ASSERT_MSG (protocolNumber == Ipv4L3Protocol::PROT_NUMBER, "unsupported protocol " << protocolNumber << ", only IPv4 is supported");
   
-  return m_rrc->Send (packet);
+  return m_nas->Send (packet);
 }
 
 
--- a/src/lte/model/lte-ue-net-device.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-net-device.h	Mon Jul 02 18:25:11 2012 +0200
@@ -22,13 +22,13 @@
 #ifndef LTE_UE_NET_DEVICE_H
 #define LTE_UE_NET_DEVICE_H
 
-#include "lte-net-device.h"
+#include "ns3/lte-net-device.h"
 #include "ns3/event-id.h"
 #include "ns3/mac48-address.h"
 #include "ns3/traced-callback.h"
 #include "ns3/nstime.h"
-#include "lte-phy.h"
-#include "lte-phy.h"
+#include "ns3/lte-phy.h"
+#include "ns3/eps-bearer.h"
 
 
 namespace ns3 {
@@ -41,6 +41,8 @@
 class LteEnbNetDevice;
 class LteUeMac;
 class LteUeRrc;
+class EpcUeNas;
+class EpcTft;
 
 /**
  * \ingroup lte
@@ -55,10 +57,14 @@
   LteUeNetDevice (void);
   /**
    * \brief Create an UE net device
-   * \param node
-   * \param phy
+   * \param node the node to which the device belongs
+   * \param phy the PHY entity
+   * \param mac the MAC entity
+   * \param rrc the RRC entity
+   * \param nas the NAS entity
+   * 
    */
-  LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc);
+  LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas);
 
   virtual ~LteUeNetDevice (void);
   virtual void DoDispose ();
@@ -68,25 +74,36 @@
   virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
   
 
-  Ptr<LteUeMac> GetMac (void);
+  Ptr<LteUeMac> GetMac (void) const;
 
-  Ptr<LteUeRrc> GetRrc ();
+  Ptr<LteUeRrc> GetRrc () const ;
 
   Ptr<LteUePhy> GetPhy (void) const;
+  
+  Ptr<EpcUeNas> GetNas (void) const;
 
+  uint64_t GetImsi () const;
+
+ 
   /**
    * \brief Set the targer eNB where the UE is registered
    * \param enb
    */
   void SetTargetEnb (Ptr<LteEnbNetDevice> enb);
+  
   /**
    * \brief Get the targer eNB where the UE is registered
    * \return the pointer to the enb
    */
   Ptr<LteEnbNetDevice> GetTargetEnb (void);
 
-  uint64_t GetImsi ();
-
+  /** 
+   * Activate a dedicated EPS bearer
+   * 
+   * \param bearer the bearer paramaters
+   * \param tft the TFT identifying the traffic that will go over the bearer
+   */
+  void ActivateDedicatedEpsBearer (EpsBearer bearer, Ptr<EpcTft> tft);
 
 protected:
   // inherited from Object
@@ -110,6 +127,7 @@
   Ptr<LteUeMac> m_mac;
   Ptr<LteUePhy> m_phy;
   Ptr<LteUeRrc> m_rrc;
+  Ptr<EpcUeNas> m_nas;
 
   uint64_t m_imsi;
   static uint64_t m_imsiCounter;
--- a/src/lte/model/lte-ue-phy-sap.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-phy-sap.h	Mon Jul 02 18:25:11 2012 +0200
@@ -48,17 +48,6 @@
   virtual void SendMacPdu (Ptr<Packet> p) = 0;
 
   /**
-  * \param ulBandwidth the UL bandwidth in RB
-  * \param dlBandwidth the DL bandwidth in RB
-  */
-  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth) = 0;
-  
-  /**
-  * \param txMode the transmissionMode of the user
-  */
-  virtual void SetTransmissionMode (uint8_t   txMode) = 0;
-
-  /**
   * \brief Send SendIdealControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel
   * \param msg the Ideal Control Message to send
   */
@@ -71,7 +60,7 @@
 /**
 * Service Access Point (SAP) offered by the PHY to the MAC
 *
-* This is the MAC SAP User, i.e., the part of the SAP that contains the MAC
+* This is the PHY SAP User, i.e., the part of the SAP that contains the MAC
 * methods called by the PHY
 */
 class LteUePhySapUser
--- a/src/lte/model/lte-ue-phy.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-phy.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -54,9 +54,7 @@
 
   // inherited from LtePhySapProvider
   virtual void SendMacPdu (Ptr<Packet> p);
-  virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
   virtual void SendIdealControlMessage (Ptr<IdealControlMessage> msg);
-  virtual void SetTransmissionMode (uint8_t txMode);
 
 private:
   LteUePhy* m_phy;
@@ -75,27 +73,15 @@
 }
 
 void
-UeMemberLteUePhySapProvider::SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
-{
-  m_phy->DoSetBandwidth (ulBandwidth, dlBandwidth);
-}
-
-void
 UeMemberLteUePhySapProvider::SendIdealControlMessage (Ptr<IdealControlMessage> msg)
 {
   m_phy->DoSendIdealControlMessage (msg);
 }
 
-void
-UeMemberLteUePhySapProvider::SetTransmissionMode (uint8_t   txMode)
-{
-  m_phy->DoSetTransmissionMode (txMode);
-}
-
 
 
 ////////////////////////////////////////
-// generic LteUePhy methods
+// LteUePhy methods
 ////////////////////////////////////////
 
 
@@ -115,10 +101,13 @@
     m_p10CqiLast (MilliSeconds (0)),
     m_a30CqiPeriocity (MilliSeconds (1)),
     // ideal behavior
-    m_a30CqiLast (MilliSeconds (0))
+    m_a30CqiLast (MilliSeconds (0)),
+    m_uePhySapUser (0),
+    m_ueCphySapUser (0)
 {
   m_amc = CreateObject <LteAmc> ();
   m_uePhySapProvider = new UeMemberLteUePhySapProvider (this);
+  m_ueCphySapProvider = new MemberLteUeCphySapProvider<LteUePhy> (this);
   m_macChTtiDelay = UL_PUSCH_TTIS_DELAY + 1; // +1 for avoiding UL/DL trigger synchronization remove 1 TTI of delay
   for (int i = 0; i < m_macChTtiDelay; i++)
     {
@@ -142,6 +131,7 @@
 {
   NS_LOG_FUNCTION (this);
   delete m_uePhySapProvider;
+  delete m_ueCphySapProvider;
   LtePhy::DoDispose ();
 }
 
@@ -214,8 +204,6 @@
 LteUePhy::DoStart ()
 {
   NS_LOG_FUNCTION (this);
-  Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
-  m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
   LtePhy::DoStart ();
 }
 
@@ -233,6 +221,21 @@
   return (m_uePhySapProvider);
 }
 
+
+void
+LteUePhy::SetLteUeCphySapUser (LteUeCphySapUser* s)
+{
+  NS_LOG_FUNCTION (this);
+  m_ueCphySapUser = s;
+}
+
+LteUeCphySapProvider*
+LteUePhy::GetLteUeCphySapProvider ()
+{
+  NS_LOG_FUNCTION (this);
+  return (m_ueCphySapProvider);
+}
+
 void
 LteUePhy::SetNoiseFigure (double nf)
 {
@@ -474,9 +477,8 @@
 {
   NS_LOG_FUNCTION (this << msg);
   Ptr<LteUeNetDevice> thisDevice = GetDevice ()->GetObject<LteUeNetDevice> ();
-  Ptr<LteEnbNetDevice> remoteDevice = thisDevice->GetTargetEnb ();
   msg->SetSourceDevice (thisDevice);
-  msg->SetDestinationDevice (remoteDevice);
+  msg->SetDestinationDevice (m_enbDevice);
   SetControlMessages (msg);
 }
 
@@ -561,6 +563,7 @@
 void
 LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
 {
+  NS_LOG_FUNCTION (this << frameNo << subframeNo);
   // trigger from eNB
   
   // update uplink transmission mask according to previous UL-CQIs
@@ -577,7 +580,7 @@
   std::list<Ptr<IdealControlMessage> > ctrlMsg = GetControlMessages ();
   if (ctrlMsg.size () > 0)
     {
-      Ptr<LtePhy> phy = GetDevice ()->GetObject<LteUeNetDevice> ()->GetTargetEnb ()->GetPhy ();
+      Ptr<LtePhy> phy = m_enbDevice->GetPhy ();
       std::list<Ptr<IdealControlMessage> >::iterator it;
       it = ctrlMsg.begin ();
       while (it != ctrlMsg.end ())
@@ -605,17 +608,7 @@
 
 
 void
-LteUePhy::SetEnbCellId (uint16_t cellId)
-{
-  m_enbCellId = cellId;
-  m_downlinkSpectrumPhy->SetCellId (cellId);
-  m_uplinkSpectrumPhy->SetCellId (cellId);
-}
-
-
-
-void
-LteUePhy::SetRnti (uint16_t rnti)
+LteUePhy::DoSetRnti (uint16_t rnti)
 {
   NS_LOG_FUNCTION (this << rnti);
   m_rnti = rnti;
@@ -623,6 +616,49 @@
 
 
 void
+LteUePhy::DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth)
+{
+  m_ulBandwidth = ulBandwidth;
+  m_dlBandwidth = dlBandwidth;
+
+  int Type0AllocationRbg[4] = {
+    10,     // RGB size 1
+    26,     // RGB size 2
+    63,     // RGB size 3
+    110     // RGB size 4
+  };  // see table 7.1.6.1-1 of 36.213
+  for (int i = 0; i < 4; i++)
+    {
+      if (dlBandwidth < Type0AllocationRbg[i])
+        {
+          m_rbgSize = i + 1;
+          break;
+        }
+    }
+  UpdateNoisePsd ();
+}
+
+void 
+LteUePhy::DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn)
+{
+  m_dlEarfcn = dlEarfcn;
+  m_ulEarfcn = ulEarfcn;
+  UpdateNoisePsd ();
+}
+
+
+void
+LteUePhy::DoSyncronizeWithEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId)
+{
+  NS_LOG_FUNCTION (this << enbDevice << cellId);
+  m_enbCellId = cellId;
+  m_enbDevice = enbDevice;
+  
+  m_downlinkSpectrumPhy->SetCellId (cellId);
+  m_uplinkSpectrumPhy->SetCellId (cellId);
+}
+
+void
 LteUePhy::DoSetTransmissionMode (uint8_t txMode)
 {
   NS_LOG_FUNCTION (this << (uint16_t)txMode);
@@ -702,7 +738,12 @@
   m_downlinkSpectrumPhy->SetTxModeGain (txMode, gain);
 }
 
-
+void 
+LteUePhy::UpdateNoisePsd ()
+{
+  Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
+  m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
+}
 
 
 } // namespace ns3
--- a/src/lte/model/lte-ue-phy.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-phy.h	Mon Jul 02 18:25:11 2012 +0200
@@ -29,6 +29,7 @@
 #include <ns3/ideal-control-messages.h>
 #include <ns3/lte-amc.h>
 #include <ns3/lte-ue-phy-sap.h>
+#include <ns3/lte-ue-cphy-sap.h>
 #include <ns3/ptr.h>
 #include <ns3/lte-amc.h>
 
@@ -48,6 +49,7 @@
 {
 
   friend class UeMemberLteUePhySapProvider;
+  friend class MemberLteUeCphySapProvider<LteUePhy>;
 
 public:
   /**
@@ -71,16 +73,28 @@
 
   /**
    * \brief Get the PHY SAP provider
-   * \return a pointer to the SAP Provider of the PHY
+   * \return a pointer to the SAP Provider 
    */
   LteUePhySapProvider* GetLteUePhySapProvider ();
 
   /**
   * \brief Set the PHY SAP User
-  * \param s a pointer to the PHY SAP user
+  * \param s a pointer to the SAP user
   */
   void SetLteUePhySapUser (LteUePhySapUser* s);
 
+  /**
+   * \brief Get the CPHY SAP provider
+   * \return a pointer to the SAP Provider
+   */
+  LteUeCphySapProvider* GetLteUeCphySapProvider ();
+
+  /**
+  * \brief Set the CPHY SAP User
+  * \param s a pointer to the SAP user
+  */
+  void SetLteUeCphySapUser (LteUeCphySapUser* s);
+
 
   /**
    * \param pw the transmission power in dBm
@@ -161,8 +175,6 @@
   virtual void DoSendIdealControlMessage (Ptr<IdealControlMessage> msg);
   virtual void ReceiveIdealControlMessage (Ptr<IdealControlMessage> msg);
   
-  virtual void DoSetTransmissionMode (uint8_t txMode);
-  
   
 
 
@@ -182,19 +194,6 @@
   void SubframeIndication (uint32_t frameNo, uint32_t subframeNo);
 
 
-  /**
-  * \param rnti the rnti assigned to the UE
-  */
-  void SetRnti (uint16_t rnti);
-
-
-  /**
-   * set the cellId of the eNb this PHY is synchronized with
-   *
-   * \param cellId the cell identifier of the eNB
-   */
-  void SetEnbCellId (uint16_t cellId);
-  
 
 
 private:
@@ -207,8 +206,17 @@
   void SetTxMode6Gain (double gain);
   void SetTxMode7Gain (double gain);
   void SetTxModeGain (uint8_t txMode, double gain);
+
+  void UpdateNoisePsd ();
   
   void QueueSubChannelsForTransmission (std::vector <int> rbMap);
+
+  // CPHY SAP methods
+  void DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
+  void DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn);
+  void DoSetTransmissionMode (uint8_t txMode);
+  void DoSetRnti (uint16_t rnti);
+  void DoSyncronizeWithEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId);
   
   std::vector <int> m_subChannelsForTransmission;
   std::vector <int> m_subChannelsForReception;
@@ -229,9 +237,13 @@
   LteUePhySapProvider* m_uePhySapProvider;
   LteUePhySapUser* m_uePhySapUser;
 
+  LteUeCphySapProvider* m_ueCphySapProvider;
+  LteUeCphySapUser* m_ueCphySapUser;
+
   uint16_t  m_rnti;
 
   uint16_t m_enbCellId;
+  Ptr<LteEnbNetDevice> m_enbDevice; // wild hack, might go away in later versions
   
   uint8_t m_transmissionMode;
   std::vector <double> m_txModeGain;
--- a/src/lte/model/lte-ue-rrc.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-rrc.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -24,11 +24,13 @@
 #include "ns3/object-factory.h"
 
 #include "lte-ue-rrc.h"
+#include "lte-enb-rrc.h"
 #include "lte-rlc.h"
 #include "lte-pdcp.h"
 #include "lte-pdcp-sap.h"
 #include "lte-radio-bearer-info.h"
-
+#include "lte-as-sap.h"
+#include "lte-enb-net-device.h"
 
 NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
 
@@ -63,30 +65,6 @@
 }
 
 
-////////////////////////////////
-// PDCP SAP Forwarder
-////////////////////////////////
-
-// class UeRrcMemberLtePdcpSapUser : public LtePdcpSapUser
-// {
-// public:
-//   MemberLtePdcpSapUser (LteUeRrc* rrc);
-//   virtual void ReceiveRrcPdu (Ptr<Packet> p);
-// private:
-//   LteUeRrc* m_rrc;EnbRrc
-// };
-
-
-// UeRrcMemberLtePdcpSapUser::UeRrcMemberLtePdcpSapUser (LteUeRrc* rrc)
-//   : m_rrc (rrc)
-// {
-// }
-
-// void UeRrcMemberLtePdcpSapUser::ReceiveRrcPdu (Ptr<Packet> p)
-// {
-//   m_rrc->DoReceiveRrcPdu (p);
-// }
-
 
 
 
@@ -97,13 +75,17 @@
 NS_OBJECT_ENSURE_REGISTERED (LteUeRrc);
 
 LteUeRrc::LteUeRrc ()
-  : m_cmacSapProvider (0),
+  : m_cphySapProvider (0),
+    m_cmacSapProvider (0),
     m_macSapProvider (0),
+    m_asSapUser (0),
     m_cellId (0)
 {
   NS_LOG_FUNCTION (this);
+  m_cphySapUser = new MemberLteUeCphySapUser<LteUeRrc> (this);
   m_cmacSapUser = new UeMemberLteUeCmacSapUser (this);
   m_pdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteUeRrc> (this);
+  m_asSapProvider = new MemberLteAsSapProvider<LteUeRrc> (this);
 }
 
 
@@ -116,8 +98,10 @@
 LteUeRrc::DoDispose ()
 {
   NS_LOG_FUNCTION (this);
+  delete m_cphySapUser;
   delete m_cmacSapUser;
   delete m_pdcpSapUser;
+  delete m_asSapProvider;
   m_rbMap.clear ();
 }
 
@@ -133,18 +117,33 @@
                    MakeObjectMapChecker<LteRadioBearerInfo> ())
     .AddAttribute ("CellId",
                    "Serving cell identifier",
-                   UintegerValue (1),
-                   MakeUintegerAccessor (&LteUeRrc::m_cellId),
+                   UintegerValue (0), // unused, read-only attribute
+                   MakeUintegerAccessor (&LteUeRrc::GetCellId),
                    MakeUintegerChecker<uint16_t> ())
     .AddAttribute ("C-RNTI",
                    "Cell Radio Network Temporary Identifier",
-                   UintegerValue (1),
-                   MakeUintegerAccessor (&LteUeRrc::m_rnti),
+                   UintegerValue (0), // unused, read-only attribute
+                   MakeUintegerAccessor (&LteUeRrc::GetRnti),
                    MakeUintegerChecker<uint16_t> ())
-  ;
+    ;
   return tid;
 }
 
+
+void
+LteUeRrc::SetLteUeCphySapProvider (LteUeCphySapProvider * s)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_cphySapProvider = s;
+}
+
+LteUeCphySapUser*
+LteUeRrc::GetLteUeCphySapUser ()
+{
+  NS_LOG_FUNCTION (this);
+  return m_cphySapUser;
+}
+
 void
 LteUeRrc::SetLteUeCmacSapProvider (LteUeCmacSapProvider * s)
 {
@@ -166,27 +165,34 @@
   m_macSapProvider = s;
 }
 
-
-
 void
-LteUeRrc::ConfigureUe (uint16_t rnti, uint16_t cellId)
+LteUeRrc::SetAsSapUser (LteAsSapUser* s)
 {
-  NS_LOG_FUNCTION (this << (uint32_t) rnti);
-  m_rnti = rnti;
-  m_cellId = cellId;
-  m_cmacSapProvider->ConfigureUe (rnti);
+  m_asSapUser = s;
+}
+
+LteAsSapProvider* 
+LteUeRrc::GetAsSapProvider ()
+{
+  return m_asSapProvider;
+}
+
+void 
+LteUeRrc::SetImsi (uint64_t imsi)
+{
+  m_imsi = imsi;
 }
 
 void
-LteUeRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId, uint8_t lcid, Ptr<EpcTft> tft)
+LteUeRrc::SetupRadioBearer (EpsBearer bearer, TypeId rlcTypeId, uint8_t lcid)
 {
-  NS_LOG_FUNCTION (this << (uint32_t)  rnti << (uint32_t) lcid);
+  NS_LOG_FUNCTION (this << (uint32_t) lcid);
 
   ObjectFactory rlcObjectFactory;
   rlcObjectFactory.SetTypeId (rlcTypeId);
   Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
   rlc->SetLteMacSapProvider (m_macSapProvider);
-  rlc->SetRnti (rnti);
+  rlc->SetRnti (m_rnti);
   rlc->SetLcId (lcid);
 
   Ptr<LteRadioBearerInfo> rbInfo = CreateObject<LteRadioBearerInfo> ();
@@ -197,7 +203,7 @@
   if (rlcTypeId != LteRlcSm::GetTypeId ())
     {
       Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
-      pdcp->SetRnti (rnti);
+      pdcp->SetRnti (m_rnti);
       pdcp->SetLcId (lcid);
       pdcp->SetLtePdcpSapUser (m_pdcpSapUser);
       pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
@@ -207,17 +213,14 @@
   
   NS_ASSERT_MSG (m_rbMap.find (lcid) == m_rbMap.end (), "bearer with same lcid already existing");
   m_rbMap.insert (std::pair<uint8_t, Ptr<LteRadioBearerInfo> > (lcid, rbInfo));
-
-
-  m_tftClassifier.Add (tft, lcid);
   
   m_cmacSapProvider->AddLc (lcid, rlc->GetLteMacSapUser ());
 }
 
 void
-LteUeRrc::ReleaseRadioBearer (uint16_t rnti, uint8_t lcid)
+LteUeRrc::ReleaseRadioBearer (uint8_t lcid)
 {
-  NS_LOG_FUNCTION (this << (uint32_t)  rnti << (uint32_t) lcid);
+  NS_LOG_FUNCTION (this << (uint32_t) lcid);
   std::map<uint8_t, Ptr<LteRadioBearerInfo> >::iterator it =   m_rbMap.find (lcid);
   NS_ASSERT_MSG (it != m_rbMap.end (), "could not find bearer with given lcid");
   m_rbMap.erase (it);
@@ -225,42 +228,29 @@
 }
 
 
-bool
-LteUeRrc::Send (Ptr<Packet> packet)
+void
+LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
 {
   NS_LOG_FUNCTION (this << packet);
-  uint8_t lcid = m_tftClassifier.Classify (packet, EpcTft::UPLINK);
+
+  // this is true until we implement Signaling Radio Bearers
+  uint8_t lcid = bid;
   LtePdcpSapProvider::TransmitRrcPduParameters params;
   params.rrcPdu = packet;
   params.rnti = m_rnti;
   params.lcid = lcid;
   std::map<uint8_t, Ptr<LteRadioBearerInfo> >::iterator it =   m_rbMap.find (lcid);
-  if (it == m_rbMap.end ())
-    {
-      NS_LOG_WARN ("could not find bearer with lcid == " << lcid);
-      return false;
-    }
-  else
-    {
-      NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending " << packet << "on LCID " << (uint32_t) lcid << " (" << packet->GetSize () << " bytes)");
-      it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitRrcPdu (params);
-      return true;
-    }
+  NS_ASSERT_MSG (it != m_rbMap.end (), "could not find bearer with lcid == " << lcid);
+  
+  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending " << packet << "on LCID " << (uint32_t) lcid << " (" << packet->GetSize () << " bytes)");
+  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitRrcPdu (params);  
 }
 
-
-void 
-LteUeRrc::SetForwardUpCallback (Callback <void, Ptr<Packet> > cb)
-{
-  m_forwardUpCallback = cb;
-}
-
-
 void
 LteUeRrc::DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params)
 {
   NS_LOG_FUNCTION (this);
-  m_forwardUpCallback (params.rrcPdu);
+  m_asSapUser->RecvData (params.rrcPdu);
 }
 
 
@@ -273,15 +263,46 @@
   NS_FATAL_ERROR ("not implemented");
 }
 
+
+void 
+LteUeRrc::DoForceCampedOnEnb (Ptr<LteEnbNetDevice> enbLteDevice, uint16_t cellId)
+{
+  NS_LOG_FUNCTION (this << cellId);
+  
+  m_cphySapProvider->SetEarfcn (enbLteDevice->GetDlEarfcn (),
+                               enbLteDevice->GetUlEarfcn ());
+  
+  m_cellId = cellId;
+  m_cphySapProvider->SyncronizeWithEnb (enbLteDevice, cellId);
+
+  // the bandwidth setting should be done upon receiving the MIB, but
+  // MIB is not implemented for the time being. 
+  m_cphySapProvider->SetBandwidth (enbLteDevice->GetUlBandwidth (),
+                                   enbLteDevice->GetDlBandwidth ());
+
+  // this is used for RRC interactions until the RRC protocol is implemented
+  m_enbRrc = enbLteDevice->GetRrc ();
+}
+
+void 
+LteUeRrc::DoConnect ()
+{
+  NS_LOG_FUNCTION (this);
+  
+  m_rnti = m_enbRrc->AddUe (m_imsi);
+  m_cmacSapProvider->ConfigureUe (m_rnti);
+  m_cphySapProvider->SetRnti (m_rnti);
+}
+
 uint16_t
-LteUeRrc::GetRnti ()
+LteUeRrc::GetRnti () const
 {
   NS_LOG_FUNCTION (this);
   return m_rnti;
 }
 
 uint16_t
-LteUeRrc::GetCellId ()
+LteUeRrc::GetCellId () const
 {
   NS_LOG_FUNCTION (this);
   return m_cellId;
@@ -303,8 +324,7 @@
 {
   NS_LOG_FUNCTION (this << " RNTI " << params.m_rnti << " txMode " << (uint16_t)params.m_transmissionMode);
   
-  // propagate the information to MAC layer
-  m_cmacSapProvider->RrcUpdateConfigurationReq (params);
+  m_cphySapProvider->SetTransmissionMode (params.m_transmissionMode);
 }
 
 
--- a/src/lte/model/lte-ue-rrc.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/model/lte-ue-rrc.h	Mon Jul 02 18:25:11 2012 +0200
@@ -24,8 +24,9 @@
 #include <ns3/object.h>
 #include <ns3/packet.h>
 #include <ns3/lte-ue-cmac-sap.h>
-#include <ns3/epc-tft-classifier.h>
 #include <ns3/lte-pdcp-sap.h>
+#include <ns3/lte-as-sap.h>
+#include <ns3/lte-ue-cphy-sap.h>
 
 #include <map>
 
@@ -36,9 +37,7 @@
 class LteUeCmacSapUser;
 class LteUeCmacSapProvider;
 class LteRadioBearerInfo;
-class LtePdcpSapUser;
-class LtePdcpSapProvider;
-
+class LteEnbRrc;
 
 /**
  *
@@ -50,6 +49,8 @@
   friend class UeMemberLteUeCmacSapUser;
   friend class UeRrcMemberLteEnbCmacSapUser;
   friend class LtePdcpSpecificLtePdcpSapUser<LteUeRrc>;
+  friend class MemberLteAsSapProvider<LteUeRrc>;
+  friend class MemberLteUeCphySapUser<LteUeRrc>;
 
 public:
   /**
@@ -71,6 +72,20 @@
 
 
   /**
+   * set the CPHY SAP this RRC should use to interact with the PHY
+   *
+   * \param s the CPHY SAP Provider
+   */
+  void SetLteUeCphySapProvider (LteUeCphySapProvider * s);
+
+  /**
+   *
+   *
+   * \return s the CPHY SAP User interface offered to the PHY by this RRC
+   */
+  LteUeCphySapUser* GetLteUeCphySapUser ();
+
+  /**
    * set the CMAC SAP this RRC should interact with
    *
    * \param s the CMAC SAP Provider to be used by this RRC
@@ -84,7 +99,6 @@
    */
   LteUeCmacSapUser* GetLteUeCmacSapUser ();
 
-
   /**
    * set the MAC SAP provider. The ue RRC does not use this
    * directly, but it needs to provide it to newly created RLC instances.
@@ -94,6 +108,27 @@
    */
   void SetLteMacSapProvider (LteMacSapProvider* s);
 
+  /** 
+   * Set the AS SAP user to interact with the NAS entity
+   * 
+   * \param s the AS SAP user
+   */
+  void SetAsSapUser (LteAsSapUser* s);
+
+  /** 
+   * 
+   * 
+   * \return the AS SAP provider exported by this RRC
+   */
+  LteAsSapProvider* GetAsSapProvider ();
+
+  /** 
+   * 
+   * 
+   * \param imsi the unique UE identifier
+   */
+  void SetImsi (uint64_t imsi);
+
   /**
    * Set UE RRC parameters
    *
@@ -102,41 +137,41 @@
    */
   void ConfigureUe (uint16_t rnti, uint16_t cellId);
 
+
+
   /**
    * Setup a new radio bearer for the given user
    *
-   * \param rnti the RNTI of the user
    * \param bearer the characteristics of the bearer to be activated
    * \param rlcTypeId the TypeId identifying the type of RLC to be used for this bearer.
    * \param lcid the logical channel id allocated for this bearer by the eNB
    * \param tft the Traffic Flow Template identifying this bearer
    *
    */
-  void SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId, uint8_t lcid, Ptr<EpcTft> tft);
+  void SetupRadioBearer (EpsBearer bearer, TypeId rlcTypeId, uint8_t lcid);
 
 
   /**
    *
    * Release the given radio bearer
    *
-   * \param rnti the C-RNTI  of the user owning the bearer
    * \param lcId the logical channel id of the bearer to be released
    */
-  void ReleaseRadioBearer (uint16_t rnti, uint8_t lcId);
+  void ReleaseRadioBearer (uint8_t lcId);
 
 
   /**
    *
    * \return the C-RNTI of the user
    */
-  uint16_t GetRnti ();
+  uint16_t GetRnti () const;
 
 
   /**
    *
    * \return the CellId of the attached Enb
    */
-  uint16_t GetCellId ();
+  uint16_t GetCellId () const;
 
   /**
    *
@@ -144,24 +179,6 @@
    */
   std::vector<uint8_t> GetLcIdVector ();
 
-
-  /** 
-   * Enqueue an IP packet on the proper bearer for uplink transmission
-   * 
-   * \param p the packet
-   * 
-   * \return true if successful, false if an error occurred
-   */
-  bool Send (Ptr<Packet> p);
-
-  /** 
-   * set the callback used to forward data packets up the stack
-   * 
-   * \param void 
-   * \param cb 
-   */
-  void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
-  
   /** 
   * message from eNB-RRC for changing UE's configuration
   * (up to now TxMode)
@@ -171,25 +188,36 @@
   
 private:
 
+  // PDCP SAP methods
   void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
 
-  // forwarded from CMAC SAP user
+  // CMAC SAP methods
   void DoLcConfigCompleted ();
 
-  Callback <void, Ptr<Packet> > m_forwardUpCallback;
+  // LTE AS SAP methods
+  void DoForceCampedOnEnb (Ptr<LteEnbNetDevice> enbDevice, uint16_t cellId);
+  void DoConnect ();
+  void DoSendData (Ptr<Packet> packet, uint8_t bid);
+
+  LteUeCphySapUser* m_cphySapUser;
+  LteUeCphySapProvider* m_cphySapProvider;
 
   LteUeCmacSapUser* m_cmacSapUser;
   LteUeCmacSapProvider* m_cmacSapProvider;
 
   LteMacSapProvider* m_macSapProvider;
   LtePdcpSapUser* m_pdcpSapUser;
+  
+  LteAsSapProvider* m_asSapProvider;
+  LteAsSapUser* m_asSapUser;
 
+  uint64_t m_imsi;
   uint16_t m_rnti;
   uint16_t m_cellId;
 
-  std::map <uint8_t, Ptr<LteRadioBearerInfo> > m_rbMap;
-  
-  EpcTftClassifier m_tftClassifier;
+  std::map <uint8_t, Ptr<LteRadioBearerInfo> > m_rbMap;  
+
+  Ptr<LteEnbRrc> m_enbRrc; // wild hack, might go away in future versions
   
 };
 
--- a/src/lte/test/epc-test-s1u-downlink.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/epc-test-s1u-downlink.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -24,6 +24,7 @@
 #include "ns3/log.h"
 #include "ns3/test.h"
 #include "ns3/epc-helper.h"
+#include "ns3/epc-enb-application.h"
 #include "ns3/packet-sink-helper.h"
 #include "ns3/udp-echo-helper.h"
 #include "ns3/point-to-point-helper.h"
@@ -37,8 +38,8 @@
 #include "ns3/boolean.h"
 #include "ns3/uinteger.h"
 #include "ns3/config.h"
-
-
+#include "ns3/eps-bearer.h"
+#include "lte-test-entities.h"
 
 namespace ns3 {
 
@@ -70,6 +71,7 @@
 };
 
 
+
 class EpcS1uDlTestCase : public TestCase
 {
 public:
@@ -152,10 +154,17 @@
       NetDeviceContainer cellDevices = csmaCell.Install (cell);
 
       // the eNB's CSMA NetDevice acting as an LTE NetDevice. 
-      Ptr<NetDevice> lteEnbNetDevice = cellDevices.Get (cellDevices.GetN () - 1);
+      Ptr<NetDevice> enbDevice = cellDevices.Get (cellDevices.GetN () - 1);
 
       // Note that the EpcEnbApplication won't care of the actual NetDevice type
-      epcHelper->AddEnb (enb, lteEnbNetDevice);      
+      epcHelper->AddEnb (enb, enbDevice);      
+
+      // Plug test RRC entity
+      Ptr<EpcEnbApplication> enbApp = enb->GetApplication (0)->GetObject<EpcEnbApplication> ();
+      NS_ASSERT_MSG (enbApp != 0, "cannot retrieve EpcEnbApplication");
+      Ptr<EpcTestRrc> rrc = CreateObject<EpcTestRrc> ();
+      rrc->SetS1SapProvider (enbApp->GetS1SapProvider ());
+      enbApp->SetS1SapUser (rrc->GetS1SapUser ());
       
       // we install the IP stack on UEs only
       InternetStackHelper internet;
@@ -191,10 +200,9 @@
           apps.Stop (Seconds (10.0));   
           enbit->ues[u].clientApp = apps.Get (0);
 
-          uint16_t rnti = u+1;
-          uint16_t lcid = 1;
-          epcHelper->ActivateEpsBearer (ueLteDevice, lteEnbNetDevice, EpcTft::Default (), rnti, lcid);
-          
+          uint64_t imsi = u+1;
+          epcHelper->AttachUe (ueLteDevice, imsi, enbDevice);
+          epcHelper->ActivateEpsBearer (ueLteDevice, imsi, EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
         } 
             
     } 
--- a/src/lte/test/epc-test-s1u-uplink.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/epc-test-s1u-uplink.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -28,6 +28,7 @@
 #include "ns3/log.h"
 #include "ns3/test.h"
 #include "ns3/epc-helper.h"
+#include "ns3/epc-enb-application.h"
 #include "ns3/packet-sink-helper.h"
 #include "ns3/point-to-point-helper.h"
 #include "ns3/csma-helper.h"
@@ -45,6 +46,7 @@
 #include "ns3/boolean.h"
 #include "ns3/uinteger.h"
 #include "ns3/config.h"
+#include "lte-test-entities.h"
 
 namespace ns3 {
 
@@ -349,10 +351,17 @@
       NetDeviceContainer cellDevices = csmaCell.Install (cell);
 
       // the eNB's CSMA NetDevice acting as an LTE NetDevice. 
-      Ptr<NetDevice> lteEnbNetDevice = cellDevices.Get (cellDevices.GetN () - 1);
+      Ptr<NetDevice> enbDevice = cellDevices.Get (cellDevices.GetN () - 1);
 
       // Note that the EpcEnbApplication won't care of the actual NetDevice type
-      epcHelper->AddEnb (enb, lteEnbNetDevice);      
+      epcHelper->AddEnb (enb, enbDevice);      
+      
+       // Plug test RRC entity
+      Ptr<EpcEnbApplication> enbApp = enb->GetApplication (0)->GetObject<EpcEnbApplication> ();
+      NS_ASSERT_MSG (enbApp != 0, "cannot retrieve EpcEnbApplication");
+      Ptr<EpcTestRrc> rrc = CreateObject<EpcTestRrc> ();
+      rrc->SetS1SapProvider (enbApp->GetS1SapProvider ());
+      enbApp->SetS1SapUser (rrc->GetS1SapUser ());
       
       // we install the IP stack on UEs only
       InternetStackHelper internet;
@@ -414,9 +423,9 @@
           clientApp.Stop (Seconds (10.0));   
           enbit->ues[u].clientApp = client;
 
-          uint16_t rnti = u+1;
-          uint16_t lcid = 1;
-          epcHelper->ActivateEpsBearer (ueLteDevice, lteEnbNetDevice, EpcTft::Default (), rnti, lcid);
+          uint64_t imsi = u+1;
+          epcHelper->AttachUe (ueLteDevice, imsi, enbDevice);
+          epcHelper->ActivateEpsBearer (ueLteDevice, imsi, EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
           
           // need this since all sinks are installed in the same node
           ++udpSinkPort; 
--- a/src/lte/test/lte-test-entities.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-entities.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -601,5 +601,72 @@
   return true;
 }
 
+
+
+
+
+
+
+
+NS_OBJECT_ENSURE_REGISTERED (EpcTestRrc);
+
+EpcTestRrc::EpcTestRrc ()
+  : m_s1SapProvider (0)
+{
+  NS_LOG_FUNCTION (this);
+  m_s1SapUser = new MemberEpcEnbS1SapUser<EpcTestRrc> (this);
+}
+
+
+EpcTestRrc::~EpcTestRrc ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+
+void
+EpcTestRrc::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  delete m_s1SapUser;
+}
+
+TypeId
+EpcTestRrc::GetTypeId (void)
+{
+  NS_LOG_FUNCTION ("EpcTestRrc::GetTypeId");
+  static TypeId tid = TypeId ("ns3::EpcTestRrc")
+    .SetParent<Object> ()
+    .AddConstructor<EpcTestRrc> ()
+  ;
+  return tid;
+}
+void 
+EpcTestRrc::SetS1SapProvider (EpcEnbS1SapProvider * s)
+{
+  m_s1SapProvider = s;
+}
+
+  
+EpcEnbS1SapUser* 
+EpcTestRrc::GetS1SapUser ()
+{
+  return m_s1SapUser;
+}
+
+void 
+EpcTestRrc::DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters request)
+{
+  EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters response;   
+  // works for a single eNB scenario with at most 1 LCID per UE
+  response.rnti = (uint16_t) request.imsi;
+  response.lcid = 1;      
+  response.success = true;
+  response.teid = request.teid;
+  m_s1SapProvider->DataRadioBearerSetupResponse (response);
+}
+
+
+
 } // namespace ns3
 
--- a/src/lte/test/lte-test-entities.h	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-entities.h	Mon Jul 02 18:25:11 2012 +0200
@@ -23,14 +23,13 @@
 
 #include "ns3/simulator.h"
 #include "ns3/test.h"
-// #include "ns3/type-id.h"
 
 #include "ns3/lte-mac-sap.h"
 #include "ns3/lte-rlc-sap.h"
 #include "ns3/lte-pdcp-sap.h"
 
 #include "ns3/net-device.h"
-
+#include <ns3/epc-enb-s1-sap.h>
 
 namespace ns3 {
 
@@ -111,13 +110,8 @@
  */
 class LteTestPdcp : public Object
 {
-    friend class LteRlcSpecificLteRlcSapUser<LteTestPdcp>;
-//   friend class EnbMacMemberLteEnbCmacSapProvider;
-//   friend class EnbMacMemberLteMacSapProvider<LteTestMac>;
-//   friend class EnbMacMemberFfMacSchedSapUser;
-//   friend class EnbMacMemberFfMacCschedSapUser;
-//   friend class EnbMacMemberLteEnbPhySapUser;
-
+  friend class LteRlcSpecificLteRlcSapUser<LteTestPdcp>;
+  
   public:
     static TypeId GetTypeId (void);
 
@@ -261,6 +255,49 @@
 
 };
 
+
+
+/**
+ * RRC stub providing a testing S1 SAP user to be used with the EpcEnbApplication
+ * 
+ */
+class EpcTestRrc : public Object
+{
+  friend class MemberEpcEnbS1SapUser<EpcTestRrc>;
+
+public:
+  EpcTestRrc ();
+  virtual ~EpcTestRrc ();
+
+  // inherited from Object
+  virtual void DoDispose (void);
+  static TypeId GetTypeId (void);
+
+  /** 
+   * Set the S1 SAP Provider
+   * 
+   * \param s the S1 SAP Provider
+   */
+  void SetS1SapProvider (EpcEnbS1SapProvider* s);
+
+  /** 
+   * 
+   * \return the S1 SAP user
+   */
+  EpcEnbS1SapUser* GetS1SapUser ();
+
+private:
+
+  // S1 SAP methods
+  void DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params);
+
+  EpcEnbS1SapProvider* m_s1SapProvider;
+  EpcEnbS1SapUser* m_s1SapUser;
+  
+
+};
+
+
 } // namespace ns3
 
 #endif /* LTE_TEST_MAC_H */
--- a/src/lte/test/lte-test-interference.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-interference.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -163,8 +163,8 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs1, bearer, EpcTft::Default ());
-  lteHelper->ActivateEpsBearer (ueDevs2, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs1, bearer);
+  lteHelper->ActivateDataRadioBearer (ueDevs2, bearer);
 
   // Use testing chunk processor in the PHY layer
   // It will be used to test that the SNR is as intended
--- a/src/lte/test/lte-test-link-adaptation.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-link-adaptation.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -195,7 +195,7 @@
   // Activate the default EPS bearer
   enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
   // Use testing chunk processor in the PHY layer
   // It will be used to test that the SNR is as intended
--- a/src/lte/test/lte-test-mimo.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-mimo.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -184,7 +184,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
   
 
   Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
--- a/src/lte/test/lte-test-pathloss-model.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-pathloss-model.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -266,7 +266,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
   
   // Use testing chunk processor in the PHY layer
   // It will be used to test that the SNR is as intended
--- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -275,7 +275,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
   Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
   Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
@@ -456,7 +456,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
   Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
   Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
--- a/src/lte/test/lte-test-phy-error-model.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-phy-error-model.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -194,7 +194,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lena->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lena->ActivateDataRadioBearer (ueDevs, bearer);
   
 
   Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
--- a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -262,7 +262,7 @@
   // Activate an EPS bearer
   enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
   
 
   Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
--- a/src/lte/test/test-lte-antenna.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/test-lte-antenna.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -131,7 +131,7 @@
   // Activate the default EPS bearer
   enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
   EpsBearer bearer (q);
-  lteHelper->ActivateEpsBearer (ueDevs, bearer, EpcTft::Default ());
+  lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
 
   // Use testing chunk processor in the PHY layer
   // It will be used to test that the SNR is as intended
--- a/src/lte/test/test-lte-epc-e2e-data.cc	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/test/test-lte-epc-e2e-data.cc	Mon Jul 02 18:25:11 2012 +0200
@@ -184,12 +184,10 @@
       ueMobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
       ueMobility.Install (ues);
       NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ues);
-      lteHelper->Attach (ueLteDevs, *enbLteDevIt);        
        
       // we install the IP stack on the UEs 
       InternetStackHelper internet;
       internet.Install (ues);
-      
 
       // assign IP address to UEs, and install applications
       for (uint32_t u = 0; u < ues.GetN (); ++u)
@@ -201,6 +199,11 @@
           // set the default gateway for the UE
           Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject<Ipv4> ());          
           ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
+
+
+          // we can now attach the UE, which will also activate the default EPS bearer
+          lteHelper->Attach (ueLteDevice, *enbLteDevIt);        
+      
   
           uint16_t dlPort = 2000;          
           for (uint32_t b = 0; b < enbit->ues.at (u).bearers.size (); ++b)
@@ -239,7 +242,7 @@
                 bearerTestData.ulClientApp = apps.Get (0);
               }
 
-              EpsBearer epsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
+              EpsBearer epsBearer (EpsBearer::NGBR_VOICE_VIDEO_GAMING);
 
               Ptr<EpcTft> tft = Create<EpcTft> ();
               EpcTft::PacketFilter dlpf;
@@ -251,7 +254,8 @@
               ulpf.remotePortEnd = ulPort;
               tft->Add (ulpf);                            
  
-              lteHelper->ActivateEpsBearer (ueLteDevice, epsBearer, tft);
+              // all data will go over the dedicated bearer instead of the default EPS bearer
+              lteHelper->ActivateDedicatedEpsBearer (ueLteDevice, epsBearer, tft);
             }
         } 
             
@@ -284,7 +288,9 @@
           uint64_t imsi = ++imsiCounter;
           for (uint32_t b = 0; b < ueit->bearers.size (); ++b)
             {
-              uint8_t lcid = b+1;
+              // LCID 0 is unused 
+              // LCID 1 is (at the moment) the Default EPS bearer, and is unused in this test program
+              uint8_t lcid = b+2;
               NS_TEST_ASSERT_MSG_EQ (lteHelper->GetPdcpStats ()->GetDlTxPackets (imsi, lcid), 
                                      ueit->bearers.at (b).numPkts, 
                                      "wrong TX PDCP packets in downlink for IMSI=" << imsi << " LCID=" << (uint16_t) lcid);
--- a/src/lte/wscript	Mon Jul 02 18:24:06 2012 +0200
+++ b/src/lte/wscript	Mon Jul 02 18:25:11 2012 +0200
@@ -53,7 +53,9 @@
         'model/lte-radio-bearer-tag.cc',
         'model/lte-phy-tag.cc',
         'model/lte-enb-phy-sap.cc',
+        'model/lte-enb-cphy-sap.cc',
         'model/lte-ue-phy-sap.cc',
+        'model/lte-ue-cphy-sap.cc',
         'model/lte-interference.cc',
         'model/lte-sinr-chunk-processor.cc',
         'model/pf-ff-mac-scheduler.cc',
@@ -63,7 +65,10 @@
         'model/epc-sgw-pgw-application.cc',
         'model/epc-tft.cc',
         'model/epc-tft-classifier.cc',
-        'model/lte-mi-error-model.cc'
+        'model/lte-mi-error-model.cc',
+        'model/epc-enb-s1-sap.cc',
+        'model/lte-as-sap.cc',
+        'model/epc-ue-nas.cc',
         ]
 
     module_test = bld.create_ns3_module_test_library('lte')
@@ -149,7 +154,9 @@
         'model/lte-radio-bearer-tag.h',
         'model/lte-phy-tag.h',
         'model/lte-enb-phy-sap.h',
+        'model/lte-enb-cphy-sap.h',
         'model/lte-ue-phy-sap.h',
+        'model/lte-ue-cphy-sap.h',
         'model/lte-interference.h',
         'model/lte-sinr-chunk-processor.h',
         'model/pf-ff-mac-scheduler.h',
@@ -160,6 +167,9 @@
         'model/epc-tft.h',
         'model/epc-tft-classifier.h',
         'model/lte-mi-error-model.h',
+        'model/epc-enb-s1-sap.h',
+        'model/lte-as-sap.h',
+        'model/epc-ue-nas.h',
         ]
 
     if (bld.env['ENABLE_EXAMPLES']):