merge
authorNicola Baldo <nbaldo@cttc.es>
Wed, 28 Sep 2011 14:12:44 +0200
changeset 8379 5e382bc62350
parent 8378 0d8107d1548b (current diff)
parent 8377 3ae363919ea3 (diff)
child 8380 f615b30c26e1
merge
src/lte/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-pdcp-header.cc	Wed Sep 28 14:12:44 2011 +0200
@@ -0,0 +1,117 @@
+/* -*-  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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#include "ns3/log.h"
+
+#include "ns3/lte-pdcp-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("LtePdcpHeader");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (LtePdcpHeader);
+
+LtePdcpHeader::LtePdcpHeader ()
+  : m_dcBit (0xff),
+    m_sequenceNumber (0xfffa)
+{
+}
+
+LtePdcpHeader::~LtePdcpHeader ()
+{
+  m_dcBit = 0xff;
+  m_sequenceNumber = 0xfffb;
+}
+
+void
+LtePdcpHeader::SetDcBit (uint8_t dcBit)
+{
+  m_dcBit = dcBit & 0x01;
+}
+
+void
+LtePdcpHeader::SetSequenceNumber (uint16_t sequenceNumber)
+{
+  m_sequenceNumber = sequenceNumber & 0x0FFF;
+}
+
+uint8_t
+LtePdcpHeader::GetDcBit () const
+{
+  return m_dcBit;
+}
+
+uint16_t
+LtePdcpHeader::GetSequenceNumber () const
+{
+  return m_sequenceNumber;
+}
+
+
+TypeId
+LtePdcpHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::LtePdcpHeader")
+    .SetParent<Header> ()
+    .AddConstructor<LtePdcpHeader> ()
+  ;
+  return tid;
+}
+
+TypeId
+LtePdcpHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void LtePdcpHeader::Print (std::ostream &os)  const
+{
+  os << "D/C=" << (uint16_t)m_dcBit;
+  os << " SN=" << m_sequenceNumber;
+}
+
+uint32_t LtePdcpHeader::GetSerializedSize (void) const
+{
+  return 2;
+}
+
+void LtePdcpHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+
+  i.WriteU8 ( (m_dcBit << 7) | (m_sequenceNumber & 0x0F00) >> 8 );
+  i.WriteU8 ( (m_sequenceNumber & 0x00FF) );
+}
+
+uint32_t LtePdcpHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  uint8_t byte_1;
+  uint8_t byte_2;
+
+  byte_1 = i.ReadU8 ();
+  byte_2 = i.ReadU8 ();
+  m_dcBit = (byte_1 & 0x80) > 7;
+  m_sequenceNumber = ((byte_1 & 0x0F) << 8) | byte_2;
+
+  return GetSerializedSize ();
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-pdcp-header.h	Wed Sep 28 14:12:44 2011 +0200
@@ -0,0 +1,76 @@
+/* -*-  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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#ifndef LTE_PDCP_HEADER_H
+#define LTE_PDCP_HEADER_H
+
+#include "ns3/header.h"
+
+#include <list>
+
+namespace ns3 {
+
+/**
+ * \ingroup lte
+ * \brief The packet header for the Packet Data Convergence Protocol (PDCP) packets
+ *
+ * This class has fields corresponding to those in an PDCP header as well as
+ * methods for serialization to and deserialization from a byte buffer.
+ * It follows 3GPP TS 36.323 Packet Data Convergence Protocol (PDCP) specification.
+ */
+class LtePdcpHeader : public Header
+{
+public:
+
+  /**
+   * \brief Constructor
+   *
+   * Creates a null header
+   */
+  LtePdcpHeader ();
+  ~LtePdcpHeader ();
+
+  void SetDcBit (uint8_t dcBit);
+  void SetSequenceNumber (uint16_t sequenceNumber);
+
+  uint8_t GetDcBit () const;
+  uint16_t GetSequenceNumber () const;
+
+  typedef enum {
+    CONTROL_PDU   = 0,
+    DATA_PDU      = 1
+  } DcBit_t;
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+private:
+  uint8_t m_dcBit;
+  uint16_t m_sequenceNumber;
+
+};
+
+}; // namespace ns3
+
+#endif // LTE_PDCP_HEADER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-pdcp.cc	Wed Sep 28 14:12:44 2011 +0200
@@ -0,0 +1,199 @@
+/* -*-  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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+
+#include "ns3/lte-pdcp.h"
+#include "ns3/lte-pdcp-header.h"
+#include "ns3/lte-pdcp-sap.h"
+
+NS_LOG_COMPONENT_DEFINE ("LtePdcp");
+
+namespace ns3 {
+
+
+class LtePdcpSpecificLteRlcSapUser : public LteRlcSapUser
+{
+public:
+  LtePdcpSpecificLteRlcSapUser (LtePdcp* pdcp);
+
+  // Interface provided to lower RLC entity (implemented from LteRlcSapUser)
+  virtual void ReceivePdcpPdu (Ptr<Packet> p);
+
+private:
+  LtePdcpSpecificLteRlcSapUser ();
+  LtePdcp* m_pdcp;
+};
+
+LtePdcpSpecificLteRlcSapUser::LtePdcpSpecificLteRlcSapUser (LtePdcp* pdcp)
+  : m_pdcp (pdcp)
+{
+}
+
+LtePdcpSpecificLteRlcSapUser::LtePdcpSpecificLteRlcSapUser ()
+{
+}
+
+void
+LtePdcpSpecificLteRlcSapUser::ReceivePdcpPdu (Ptr<Packet> p)
+{
+  m_pdcp->DoReceivePdu (p);
+}
+
+///////////////////////////////////////
+
+NS_OBJECT_ENSURE_REGISTERED (LtePdcp);
+
+LtePdcp::LtePdcp ()
+  : m_pdcpSapUser (0),
+    m_rlcSapProvider (0),
+    m_rnti (0),
+    m_lcid (0),
+    m_txSequenceNumber (0),
+    m_rxSequenceNumber (0)
+{
+  NS_LOG_FUNCTION (this);
+  m_pdcpSapProvider = new LtePdcpSpecificLtePdcpSapProvider<LtePdcp> (this);
+  m_rlcSapUser = new LtePdcpSpecificLteRlcSapUser (this);
+
+  Simulator::ScheduleNow (&LtePdcp::Start, this);
+}
+
+TypeId
+LtePdcp::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::LtePdcp")
+    .SetParent<Object> ()
+    .AddTraceSource ("TxPDU",
+                     "PDU transmission notified to the RLC.",
+                     MakeTraceSourceAccessor (&LtePdcp::m_txPdu))
+    .AddTraceSource ("RxPDU",
+                     "PDU received.",
+                     MakeTraceSourceAccessor (&LtePdcp::m_rxPdu))
+    ;
+  return tid;
+}
+
+void
+LtePdcp::SetRnti (uint16_t rnti)
+{
+  NS_LOG_FUNCTION (this << (uint32_t) rnti);
+  m_rnti = rnti;
+}
+
+void
+LtePdcp::SetLcId (uint8_t lcId)
+{
+  NS_LOG_FUNCTION (this << (uint32_t) lcId);
+  m_lcid = lcId;
+}
+
+LtePdcp::~LtePdcp ()
+{
+  NS_LOG_FUNCTION (this);
+  delete (m_pdcpSapProvider);
+  delete (m_rlcSapUser);
+}
+
+void
+LtePdcp::SetLtePdcpSapUser (LtePdcpSapUser * s)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_pdcpSapUser = s;
+}
+
+LtePdcpSapProvider*
+LtePdcp::GetLtePdcpSapProvider ()
+{
+  NS_LOG_FUNCTION (this);
+  return m_pdcpSapProvider;
+}
+
+void
+LtePdcp::SetLteRlcSapProvider (LteRlcSapProvider * s)
+{
+  NS_LOG_FUNCTION (this << s);
+  m_rlcSapProvider = s;
+}
+
+LteRlcSapUser*
+LtePdcp::GetLteRlcSapUser ()
+{
+  NS_LOG_FUNCTION (this);
+  return m_rlcSapUser;
+}
+
+////////////////////////////////////////
+
+void
+LtePdcp::DoTransmitRrcPdu (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION (this);
+
+  LtePdcpHeader pdcpHeader;
+  pdcpHeader.SetSequenceNumber (m_txSequenceNumber);
+
+  m_txSequenceNumber++;
+  if (m_txSequenceNumber > m_maxPdcpSn)
+    {
+      m_txSequenceNumber = 0;
+    }
+
+  pdcpHeader.SetDcBit (LtePdcpHeader::DATA_PDU);
+
+  NS_LOG_LOGIC ("PDCP header: " << pdcpHeader);
+  p->AddHeader (pdcpHeader);
+
+  LteRlcSapProvider::TransmitPdcpPduParameters params;
+  params.rnti = m_rnti;
+  params.lcid = m_lcid;
+  params.pdcpPdu = p;
+
+  m_rlcSapProvider->TransmitPdcpPdu (params);
+}
+
+void
+LtePdcp::DoReceivePdu (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION (this);
+
+  LtePdcpHeader pdcpHeader;
+  p->RemoveHeader (pdcpHeader);
+  NS_LOG_LOGIC ("PDCP header: " << pdcpHeader);
+
+  m_rxSequenceNumber = pdcpHeader.GetSequenceNumber () + 1;
+  if (m_rxSequenceNumber > m_maxPdcpSn)
+    {
+      m_rxSequenceNumber = 0;
+    }
+
+  m_pdcpSapUser->ReceiveRrcPdu (p);
+
+}
+
+void
+LtePdcp::Start ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-pdcp.h	Wed Sep 28 14:12:44 2011 +0200
@@ -0,0 +1,133 @@
+/* -*-  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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#ifndef LTE_PDCP_H
+#define LTE_PDCP_H
+
+#include "ns3/traced-value.h"
+#include "ns3/trace-source-accessor.h"
+
+#include "ns3/object.h"
+
+#include "ns3/lte-pdcp-sap.h"
+#include "ns3/lte-rlc-sap.h"
+
+namespace ns3 {
+
+/**
+ * LTE PDCP entity, see 3GPP TS 36.323
+ */
+class LtePdcp : public Object // SimpleRefCount<LtePdcp>
+{
+  friend class LtePdcpSpecificLteRlcSapUser;
+  friend class LtePdcpSpecificLtePdcpSapProvider<LtePdcp>;
+public:
+  LtePdcp ();
+  virtual ~LtePdcp ();
+  static TypeId GetTypeId (void);
+
+  void Start ();
+
+  /**
+   *
+   *
+   * \param rnti
+   */
+  void SetRnti (uint16_t rnti);
+
+  /**
+   *
+   *
+   * \param lcId
+   */
+  void SetLcId (uint8_t lcId);
+
+  /**
+   *
+   *
+   * \param s the PDCP SAP user to be used by this LTE_PDCP
+   */
+  void SetLtePdcpSapUser (LtePdcpSapUser * s);
+
+  /**
+   *
+   *
+   * \param s the PDCP SAP Provider interface offered to the RRC by this LTE_PDCP
+   */
+  LtePdcpSapProvider* GetLtePdcpSapProvider ();
+
+  /**
+   *
+   *
+   * \param s the RLC SAP Provider to be used by this LTE_PDCP
+   */
+  void SetLteRlcSapProvider (LteRlcSapProvider * s);
+
+  /**
+   *
+   *
+   * \param s the RLC SAP User interface offered to the RLC by this LTE_PDCP
+   */
+  LteRlcSapUser* GetLteRlcSapUser ();
+
+
+protected:
+  // Interface provided to upper RRC entity
+  virtual void DoTransmitRrcPdu (Ptr<Packet> p);
+
+  LtePdcpSapUser* m_pdcpSapUser;
+  LtePdcpSapProvider* m_pdcpSapProvider;
+
+  // Interface provided to lower RLC entity
+  virtual void DoReceivePdu (Ptr<Packet> p);
+
+  LteRlcSapUser* m_rlcSapUser;
+  LteRlcSapProvider* m_rlcSapProvider;
+
+  uint16_t m_rnti;
+  uint8_t m_lcid;
+
+  /**
+   * Used to inform of a PDU delivery to the RLC SAP provider
+   */
+  TracedCallback<uint16_t, uint8_t, uint32_t> m_txPdu;
+  /**
+   * Used to inform of a PDU reception from the RLC SAP user
+   */
+  TracedCallback<uint16_t, uint8_t, uint32_t, uint64_t> m_rxPdu;
+
+private:
+  /**
+   * State variables. See section 7.1 in TS 36.323
+   */
+  uint16_t m_txSequenceNumber;
+  uint16_t m_rxSequenceNumber;
+
+  /**
+   * Constants. See section 7.2 in TS 36.323
+   */
+  static const uint16_t m_maxPdcpSn = 4095;
+
+};
+
+
+} // namespace ns3
+
+#endif // LTE_PDCP_H
--- a/src/lte/model/lte-rlc-header.cc	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/model/lte-rlc-header.cc	Wed Sep 28 14:12:44 2011 +0200
@@ -131,17 +131,31 @@
 {
   std::list <uint8_t>::const_iterator it1 = m_extensionBits.begin ();
   std::list <uint16_t>::const_iterator it2 = m_lengthIndicators.begin ();
-  uint16_t i = 1;
 
   os << "Len=" << m_headerLength;
   os << " FI=" << (uint16_t)m_framingInfo;
   os << " E=" << (uint16_t)(*it1);
   os << " SN=" << m_sequenceNumber;
 
-  for (it1++; *it1 && *it2; i++, it1++, it2++)
+  it1++;
+  if (it1 != m_extensionBits.end ())
+    {
+      os << " E=";
+    }
+  while ( it1 != m_extensionBits.end () )
     {
-      os << " E(" << i << ")=" << (uint16_t)(*it1);
-      os << " LI(" << i << ")=" << (uint16_t)(*it2);
+      os << (uint16_t)(*it1);
+      it1++;
+    }
+
+  if (it2 != m_lengthIndicators.end ())
+    {
+      os << " LI=";
+    }
+  while ( it2 != m_lengthIndicators.end () )
+    {
+      os << (uint16_t)(*it2) << " ";
+      it2++;
     }
 }
 
--- a/src/lte/model/lte-rlc-tag.h	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/model/lte-rlc-tag.h	Wed Sep 28 14:12:44 2011 +0200
@@ -56,7 +56,7 @@
   /**
    * Get the instant when the RLC delivers the PDU to the MAC SAP provider
    */
-  Time  getSenderTimestamp (void) const
+  Time  GetSenderTimestamp (void) const
   {
     return m_senderTimestamp;
   }
@@ -65,7 +65,7 @@
    * Set the sender timestamp
    * @param senderTimestamp time stamp of the instant when the RLC delivers the PDU to the MAC SAP provider
    */
-  void  setSenderTimestamp (Time senderTimestamp)
+  void  SetSenderTimestamp (Time senderTimestamp)
   {
     this->m_senderTimestamp = senderTimestamp;
   }
--- a/src/lte/model/lte-rlc-um.cc	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/model/lte-rlc-um.cc	Wed Sep 28 14:12:44 2011 +0200
@@ -24,6 +24,7 @@
 #include "ns3/lte-rlc-header.h"
 #include "ns3/lte-rlc-um.h"
 #include "ns3/lte-rlc-sdu-status-tag.h"
+#include "ns3/lte-rlc-tag.h"
 
 NS_LOG_COMPONENT_DEFINE ("LteRlcUm");
 
@@ -32,7 +33,8 @@
 NS_OBJECT_ENSURE_REGISTERED (LteRlcUm);
 
 LteRlcUm::LteRlcUm ()
-  : m_sequenceNumber (0),
+  : m_txBufferSize (0),
+    m_sequenceNumber (0),
     m_vrUr (0),
     m_vrUx (0),
     m_vrUh (0),
@@ -69,26 +71,41 @@
 {
   NS_LOG_FUNCTION (this);
 
+  /** Store arrival time */
+  Time now = Simulator::Now ();
+  RlcTag timeTag (now);
+  p->AddPacketTag (timeTag);
+
   /** Store PDCP PDU */
 
   LteRlcSduStatusTag tag;
   tag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
   p->AddPacketTag (tag);
 
+  NS_LOG_LOGIC ("Tx Buffer: New packet added");
   m_txBuffer.push_back (p);
-  NS_LOG_LOGIC ("Tx Buffer. New packet added. New size = " << m_txBuffer.size() );
+  m_txBufferSize += p->GetSize ();
+  NS_LOG_LOGIC ("NumOfBuffers = " << m_txBuffer.size() );
+  NS_LOG_LOGIC ("txBufferSize = " << m_txBufferSize);
 
   /** Report Buffer Status */
 
+  RlcTag holTimeTag;
+  m_txBuffer.front ()->PeekPacketTag (holTimeTag);
+  Time holDelay = now - holTimeTag.GetSenderTimestamp ();
+
   LteMacSapProvider::ReportBufferStatusParameters r;
   r.rnti = m_rnti;
   r.lcid = m_lcid;
-  r.txQueueSize = p->GetSize ();
-  r.txQueueHolDelay = 0;
+  r.txQueueSize = m_txBufferSize + 2 * m_txBuffer.size (); // Data in tx queue + estimated headers size
+  r.txQueueHolDelay = holDelay.GetMilliSeconds () ;
   r.retxQueueSize = 0;
   r.retxQueueHolDelay = 0;
   r.statusPduSize = 0;
 
+  NS_LOG_LOGIC ("Send ReportBufferStatus");
+  NS_LOG_LOGIC ("Queue size = " << r.txQueueSize);
+  NS_LOG_LOGIC ("HOL delay = " << r.txQueueHolDelay);
   m_macSapProvider->ReportBufferStatus (r);
 }
 
@@ -129,13 +146,12 @@
 
   NS_LOG_LOGIC ("SDUs in TxBuffer  = " << m_txBuffer.size ());
   NS_LOG_LOGIC ("First SDU buffer  = " << *(m_txBuffer.begin()));
-  if (m_txBuffer.size () > 0)
-    {
-      NS_LOG_LOGIC ("First SDU size    = " << (*(m_txBuffer.begin()))->GetSize ());
-    }
+  NS_LOG_LOGIC ("First SDU size    = " << (*(m_txBuffer.begin()))->GetSize ());
   NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize);
   NS_LOG_LOGIC ("Remove SDU from TxBuffer");
   Ptr<Packet> firstSegment = (*(m_txBuffer.begin ()))->Copy ();
+  m_txBufferSize -= (*(m_txBuffer.begin()))->GetSize ();
+  NS_LOG_LOGIC ("txBufferSize      = " << m_txBufferSize );
   m_txBuffer.erase (m_txBuffer.begin ());
 
   while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) )
@@ -172,11 +188,13 @@
           // Give back the remaining segment to the transmission buffer
           firstSegment->RemoveAtStart (nextSegmentSize);
           m_txBuffer.insert (m_txBuffer.begin (), firstSegment);
+          m_txBufferSize += (*(m_txBuffer.begin()))->GetSize ();
           firstSegment = 0; // TODO how to put a null ptr to Packet?
 
           NS_LOG_LOGIC ("    TX buffer: Give back the remaining segment");
           NS_LOG_LOGIC ("    TX buffers = " << m_txBuffer.size ());
           NS_LOG_LOGIC ("    Front buffer size = " << (*(m_txBuffer.begin()))->GetSize ());
+          NS_LOG_LOGIC ("    txBufferSize = " << m_txBufferSize );
 
           // Add Segment to Data field
           dataFieldAddedSize = newSegment->GetSize ();
@@ -255,7 +273,9 @@
 
           // (more segments)
           firstSegment = (*(m_txBuffer.begin ()))->Copy ();
+          m_txBufferSize -= (*(m_txBuffer.begin()))->GetSize ();
           m_txBuffer.erase (m_txBuffer.begin ());
+          NS_LOG_LOGIC ("        txBufferSize = " << m_txBufferSize );
         }
 
     }
--- a/src/lte/model/lte-rlc-um.h	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/model/lte-rlc-um.h	Wed Sep 28 14:12:44 2011 +0200
@@ -68,6 +68,7 @@
   void ReassembleAndDeliver (Ptr<Packet> packet);
 
 private:
+  uint32_t m_txBufferSize;
   std::vector < Ptr<Packet> > m_txBuffer;       // Transmission buffer
   std::map <uint16_t, Ptr<Packet> > m_rxBuffer; // Reception buffer
   std::vector < Ptr<Packet> > m_reasBuffer;     // Reassembling buffer
--- a/src/lte/model/lte-rlc.cc	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/model/lte-rlc.cc	Wed Sep 28 14:12:44 2011 +0200
@@ -109,9 +109,9 @@
 }
 
 void
-LteRlc::SetRnti (uint8_t rnti)
+LteRlc::SetRnti (uint16_t rnti)
 {
-  NS_LOG_FUNCTION (this << (uint32_t)  rnti);
+  NS_LOG_FUNCTION (this << (uint32_t) rnti);
   m_rnti = rnti;
 }
 
@@ -199,7 +199,7 @@
   Time delay;
   if (p->FindFirstMatchingByteTag(rlcTag))
     {
-      delay = Simulator::Now() - rlcTag.getSenderTimestamp ();
+      delay = Simulator::Now() - rlcTag.GetSenderTimestamp ();
     }
   NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize () << delay.GetNanoSeconds ());
   m_rxPdu(m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds () );
--- a/src/lte/model/lte-rlc.h	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/model/lte-rlc.h	Wed Sep 28 14:12:44 2011 +0200
@@ -61,7 +61,7 @@
    *
    * \param rnti
    */
-  void SetRnti (uint8_t rnti);
+  void SetRnti (uint16_t rnti);
 
   /**
    *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-entities.cc	Wed Sep 28 14:12:44 2011 +0200
@@ -0,0 +1,382 @@
+/* -*-  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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#include "ns3/simulator.h"
+#include "ns3/log.h"
+
+#include "ns3/lte-rlc-header.h"
+#include "ns3/lte-pdcp-header.h"
+
+#include "ns3/lte-test-entities.h"
+
+NS_LOG_COMPONENT_DEFINE ("LteTestEntities");
+
+using namespace ns3;
+
+
+/////////////////////////////////////////////////////////////////////
+
+TypeId
+LteTestRrc::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::LteTestRrc")
+    .SetParent<Object> ()
+    .AddConstructor<LteTestRrc> ()
+    ;
+
+  return tid;
+}
+
+LteTestRrc::LteTestRrc ()
+{
+  NS_LOG_FUNCTION (this);
+  m_pdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteTestRrc> (this);
+  Simulator::ScheduleNow (&LteTestRrc::Start, this);
+}
+
+LteTestRrc::~LteTestRrc ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+LteTestRrc::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  delete m_pdcpSapUser;
+}
+
+void
+LteTestRrc::SetLtePdcpSapProvider (LtePdcpSapProvider* s)
+{
+  m_pdcpSapProvider = s;
+}
+
+LtePdcpSapUser*
+LteTestRrc::GetLtePdcpSapUser (void)
+{
+  return m_pdcpSapUser;
+}
+
+
+std::string
+LteTestRrc::GetDataReceived (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  return m_receivedData;
+}
+
+
+/**
+ * PDCP SAP
+ */
+
+void
+LteTestRrc::DoReceiveRrcPdu (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_LOGIC ("PDU received = " << (*p));
+
+  uint32_t dataLen = p->GetSize ();
+  uint8_t *buf = new uint8_t[dataLen];
+  p->CopyData (buf, dataLen);
+  m_receivedData = std::string ((char *)buf, dataLen);
+
+  NS_LOG_LOGIC (m_receivedData);
+
+  delete [] buf;
+}
+
+/**
+ * START
+ */
+
+void
+LteTestRrc::Start ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+LteTestRrc::SendData (Time at, std::string dataToSend)
+{
+  NS_LOG_FUNCTION (this);
+
+  LtePdcpSapProvider::TransmitRrcPduParameters p;
+  p.rnti = 1111;
+  p.lcid = 222;
+
+  NS_LOG_LOGIC ("Data(" << dataToSend.length () << ") = " << dataToSend.data ());
+  p.rrcPdu = Create<Packet> ((uint8_t *) dataToSend.data (), dataToSend.length ());
+
+  NS_LOG_LOGIC ("Packet(" << p.rrcPdu->GetSize () << ")");
+  Simulator::Schedule (at, &LtePdcpSapProvider::TransmitRrcPdu, m_pdcpSapProvider, p);
+  Simulator::Run ();
+}
+
+/////////////////////////////////////////////////////////////////////
+
+TypeId
+LteTestPdcp::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::LteTestPdcp")
+    .SetParent<Object> ()
+    .AddConstructor<LteTestPdcp> ()
+    ;
+
+  return tid;
+}
+
+LteTestPdcp::LteTestPdcp ()
+{
+  NS_LOG_FUNCTION (this);
+  m_rlcSapUser = new LteRlcSpecificLteRlcSapUser<LteTestPdcp> (this);
+  Simulator::ScheduleNow (&LteTestPdcp::Start, this);
+}
+
+LteTestPdcp::~LteTestPdcp ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+LteTestPdcp::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  delete m_rlcSapUser;
+}
+
+void
+LteTestPdcp::SetLteRlcSapProvider (LteRlcSapProvider* s)
+{
+  m_rlcSapProvider = s;
+}
+
+LteRlcSapUser*
+LteTestPdcp::GetLteRlcSapUser (void)
+{
+  return m_rlcSapUser;
+}
+
+
+std::string
+LteTestPdcp::GetDataReceived (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  return m_receivedData;
+}
+
+
+/**
+ * RLC SAP
+ */
+
+void
+LteTestPdcp::DoReceivePdcpPdu (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_LOGIC ("PDU received = " << (*p));
+
+  uint32_t dataLen = p->GetSize ();
+  uint8_t *buf = new uint8_t[dataLen];
+  p->CopyData (buf, dataLen);
+  m_receivedData = std::string ((char *)buf, dataLen);
+
+  NS_LOG_LOGIC (m_receivedData);
+
+  delete [] buf;
+}
+
+/**
+ * START
+ */
+
+void
+LteTestPdcp::Start ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+LteTestPdcp::SendData (Time time, std::string dataToSend)
+{
+  NS_LOG_FUNCTION (this);
+
+  LteRlcSapProvider::TransmitPdcpPduParameters p;
+  p.rnti = 1111;
+  p.lcid = 222;
+
+  NS_LOG_LOGIC ("Data(" << dataToSend.length () << ") = " << dataToSend.data ());
+  p.pdcpPdu = Create<Packet> ((uint8_t *) dataToSend.data (), dataToSend.length ());
+
+  NS_LOG_LOGIC ("Packet(" << p.pdcpPdu->GetSize () << ")");
+  Simulator::Schedule (time, &LteRlcSapProvider::TransmitPdcpPdu, m_rlcSapProvider, p);
+  Simulator::Run ();
+}
+
+/////////////////////////////////////////////////////////////////////
+
+TypeId
+LteTestMac::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::LteTestMac")
+    .SetParent<Object> ()
+    .AddConstructor<LteTestMac> ()
+    ;
+
+  return tid;
+}
+
+LteTestMac::LteTestMac ()
+{
+  NS_LOG_FUNCTION (this);
+  m_macSapProvider = new EnbMacMemberLteMacSapProvider<LteTestMac> (this);
+  m_macSapUser = 0;
+  m_macLoopback = 0;
+  m_pdcpHeaderPresent = false;
+  m_txOpportunityMode = MANUAL_MODE;
+//   m_cmacSapProvider = new EnbMacMemberLteEnbCmacSapProvider (this);
+//   m_schedSapUser = new EnbMacMemberFfMacSchedSapUser (this);
+//   m_cschedSapUser = new EnbMacMemberFfMacCschedSapUser (this);
+//   m_enbPhySapUser = new EnbMacMemberLteEnbPhySapUser (this);
+}
+
+LteTestMac::~LteTestMac ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+LteTestMac::DoDispose ()
+{
+  NS_LOG_FUNCTION (this);
+  delete m_macSapProvider;
+//   delete m_cmacSapProvider;
+//   delete m_schedSapUser;
+//   delete m_cschedSapUser;
+//   delete m_enbPhySapUser;
+}
+
+void
+LteTestMac::SetLteMacSapUser (LteMacSapUser* s)
+{
+  m_macSapUser = s;
+}
+
+LteMacSapProvider*
+LteTestMac::GetLteMacSapProvider (void)
+{
+  return m_macSapProvider;
+}
+
+void
+LteTestMac::SetLteMacLoopback (Ptr<LteTestMac> s)
+{
+  m_macLoopback = s;
+}
+
+std::string
+LteTestMac::GetDataReceived (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  return m_receivedData;
+}
+
+void
+LteTestMac::SendTxOpportunity (Time time, uint32_t bytes)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_LOGIC ("Bytes = " << bytes);
+
+  Simulator::Schedule (time, &LteMacSapUser::NotifyTxOpportunity, m_macSapUser, bytes);
+  Simulator::Run ();
+}
+
+void
+LteTestMac::SetPdcpHeaderPresent (bool present)
+{
+  NS_LOG_FUNCTION (this);
+  m_pdcpHeaderPresent = present;
+}
+
+void
+LteTestMac::SetTxOpportunityMode (uint8_t mode)
+{
+  NS_LOG_FUNCTION (this);
+  m_txOpportunityMode = mode;
+}
+
+
+/**
+ * MAC SAP
+ */
+
+void
+LteTestMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
+{
+  NS_LOG_FUNCTION (this);
+
+  if (m_macLoopback)
+    {
+      Simulator::Schedule (Seconds (0.1), &LteMacSapUser::ReceivePdu,
+                           m_macLoopback->m_macSapUser, params.pdu);
+    }
+  else
+    {
+      LteRlcHeader rlcHeader;
+      LtePdcpHeader pdcpHeader;
+
+      // Remove RLC header
+      params.pdu->RemoveHeader (rlcHeader);
+      NS_LOG_LOGIC ("RLC header: " << rlcHeader);
+
+      // Remove PDCP header, if present
+      if (m_pdcpHeaderPresent)
+        {
+          params.pdu->RemoveHeader (pdcpHeader);
+          NS_LOG_LOGIC ("PDCP header: " << pdcpHeader);
+        }
+
+      // Copy data to a string
+      uint32_t dataLen = params.pdu->GetSize ();
+      uint8_t *buf = new uint8_t[dataLen];
+      params.pdu->CopyData (buf, dataLen);
+      m_receivedData = std::string ((char *)buf, dataLen);
+
+      NS_LOG_LOGIC ("Data (" << dataLen << ") = " << m_receivedData);
+      delete [] buf;
+    }
+}
+
+void
+LteTestMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params)
+{
+  NS_LOG_FUNCTION (this);
+  NS_LOG_LOGIC ("Queue size = " << params.txQueueSize);
+
+  if ((m_txOpportunityMode == AUTOMATIC_MODE) && params.txQueueSize)
+    {
+      Simulator::Schedule (Seconds (0.1), &LteMacSapUser::NotifyTxOpportunity,
+                           m_macSapUser, params.txQueueSize + 2); // TODO Including RLC header size??? Not clean
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-entities.h	Wed Sep 28 14:12:44 2011 +0200
@@ -0,0 +1,202 @@
+/* -*-  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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#ifndef LTE_TEST_ENTITIES_H
+#define LTE_TEST_ENTITIES_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"
+
+
+using namespace ns3;
+
+
+/**
+ * This class implements a testing RRC entity
+ */
+class LteTestRrc : public Object
+{
+    friend class LtePdcpSpecificLtePdcpSapUser<LteTestRrc>;
+//   friend class EnbMacMemberLteEnbCmacSapProvider;
+//   friend class EnbMacMemberLteMacSapProvider<LteTestMac>;
+//   friend class EnbMacMemberFfMacSchedSapUser;
+//   friend class EnbMacMemberFfMacCschedSapUser;
+//   friend class EnbMacMemberLteEnbPhySapUser;
+
+  public:
+    static TypeId GetTypeId (void);
+
+    LteTestRrc (void);
+    virtual ~LteTestRrc (void);
+    virtual void DoDispose (void);
+
+
+    /**
+    * \brief Set the PDCP SAP provider
+    * \param s a pointer to the PDCP SAP provider
+    */
+    void SetLtePdcpSapProvider (LtePdcpSapProvider* s);
+    /**
+    * \brief Get the PDCP SAP user
+    * \return a pointer to the SAP user of the RLC
+    */
+    LtePdcpSapUser* GetLtePdcpSapUser (void);
+
+    void Start ();
+
+    void SendData (Time at, std::string dataToSend);
+    std::string GetDataReceived (void);
+
+  private:
+    // Interface forwarded by LtePdcpSapUser
+    virtual void DoReceiveRrcPdu (Ptr<Packet> p);
+
+    LtePdcpSapUser* m_pdcpSapUser;
+    LtePdcpSapProvider* m_pdcpSapProvider;
+
+    std::string m_receivedData;
+
+};
+
+/////////////////////////////////////////////////////////////////////
+
+/**
+ * This class implements a testing PDCP entity
+ */
+class LteTestPdcp : public Object
+{
+    friend class LteRlcSpecificLteRlcSapUser<LteTestPdcp>;
+//   friend class EnbMacMemberLteEnbCmacSapProvider;
+//   friend class EnbMacMemberLteMacSapProvider<LteTestMac>;
+//   friend class EnbMacMemberFfMacSchedSapUser;
+//   friend class EnbMacMemberFfMacCschedSapUser;
+//   friend class EnbMacMemberLteEnbPhySapUser;
+
+  public:
+    static TypeId GetTypeId (void);
+
+    LteTestPdcp (void);
+    virtual ~LteTestPdcp (void);
+    virtual void DoDispose (void);
+
+
+    /**
+    * \brief Set the RLC SAP provider
+    * \param s a pointer to the RLC SAP provider
+    */
+    void SetLteRlcSapProvider (LteRlcSapProvider* s);
+    /**
+    * \brief Get the RLC SAP user
+    * \return a pointer to the SAP user of the RLC
+    */
+    LteRlcSapUser* GetLteRlcSapUser (void);
+
+    void Start ();
+
+    void SendData (Time time, std::string dataToSend);
+    std::string GetDataReceived (void);
+
+  private:
+    // Interface forwarded by LteRlcSapUser
+    virtual void DoReceivePdcpPdu (Ptr<Packet> p);
+
+    LteRlcSapUser* m_rlcSapUser;
+    LteRlcSapProvider* m_rlcSapProvider;
+
+    std::string m_receivedData;
+
+};
+
+/////////////////////////////////////////////////////////////////////
+
+/**
+ * This class implements a testing loopback MAC layer
+ */
+class LteTestMac : public Object
+{
+//   friend class EnbMacMemberLteEnbCmacSapProvider;
+    friend class EnbMacMemberLteMacSapProvider<LteTestMac>;
+//   friend class EnbMacMemberFfMacSchedSapUser;
+//   friend class EnbMacMemberFfMacCschedSapUser;
+//   friend class EnbMacMemberLteEnbPhySapUser;
+
+  public:
+    static TypeId GetTypeId (void);
+
+    LteTestMac (void);
+    virtual ~LteTestMac (void);
+    virtual void DoDispose (void);
+
+    void SendTxOpportunity (Time, uint32_t);
+    std::string GetDataReceived (void);
+
+    /**
+     * \brief Set the MAC SAP user
+     * \param s a pointer to the MAC SAP user
+     */
+    void SetLteMacSapUser (LteMacSapUser* s);
+    /**
+     * \brief Get the MAC SAP provider
+     * \return a pointer to the SAP provider of the MAC
+     */
+    LteMacSapProvider* GetLteMacSapProvider (void);
+
+    /**
+     * \brief Set the other side of the MAC Loopback
+     * \param s a pointer to the other side of the MAC loopback
+     */
+    void SetLteMacLoopback (Ptr<LteTestMac> s);
+
+    /**
+     *
+     */
+    void SetPdcpHeaderPresent (bool present);
+
+    /**
+     *
+     */
+    void SetTxOpportunityMode (uint8_t mode);
+
+    typedef enum {
+      MANUAL_MODE     = 0,
+      AUTOMATIC_MODE  = 1
+    } TxOpportunityMode_t;
+
+  private:
+    // forwarded from LteMacSapProvider
+    void DoTransmitPdu (LteMacSapProvider::TransmitPduParameters);
+    void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters);
+
+    LteMacSapProvider* m_macSapProvider;
+    LteMacSapUser* m_macSapUser;
+    Ptr<LteTestMac> m_macLoopback;
+
+    std::string m_receivedData;
+
+    bool m_pdcpHeaderPresent;
+    bool m_txOpportunityMode;
+
+};
+
+#endif /* LTE_TEST_MAC_H */
--- a/src/lte/test/lte-test-rlc-um-transmitter.cc	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/test/lte-test-rlc-um-transmitter.cc	Wed Sep 28 14:12:44 2011 +0200
@@ -20,7 +20,6 @@
 
 #include "ns3/simulator.h"
 #include "ns3/log.h"
-#include "ns3/string.h"
 
 #include "ns3/lte-rlc-header.h"
 #include "ns3/lte-rlc-um.h"
@@ -47,6 +46,7 @@
   AddTestCase (new LteRlcUmTransmitterOneSduTestCase ("One SDU, one PDU"));
   AddTestCase (new LteRlcUmTransmitterSegmentationTestCase ("Segmentation"));
   AddTestCase (new LteRlcUmTransmitterConcatenationTestCase ("Concatenation"));
+  AddTestCase (new LteRlcUmTransmitterReportBufferStatusTestCase ("ReportBufferStatus primitive"));
 
 }
 
@@ -68,12 +68,13 @@
 {
   LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
   LogComponentEnable ("LteRlcUmTransmitterTest", logLevel);
+  LogComponentEnable ("LteTestEntities", logLevel);
   LogComponentEnable ("LteRlc", logLevel);
   LogComponentEnable ("LteRlcUm", logLevel);
   LogComponentEnable ("LteRlcHeader", logLevel);
 
   uint16_t rnti = 1111;
-  uint16_t lcid = 2222;
+  uint8_t lcid = 222;
 
   Packet::EnablePrinting ();
 
@@ -129,7 +130,7 @@
   dataToSend = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   txPdcp->SendData (Seconds (0.0), dataToSend);
 
-  txMac->SendTxOpportunity (28);
+  txMac->SendTxOpportunity (Seconds (0.1), 28);
   NS_TEST_ASSERT_MSG_EQ ("ABCDEFGHIJKLMNOPQRSTUVWXYZ", txMac->GetDataReceived (), "SDU is not OK");
 
   Simulator::Destroy ();
@@ -165,16 +166,16 @@
   dataToSend = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   txPdcp->SendData (Seconds (0.0), dataToSend);
 
-  txMac->SendTxOpportunity (10);
+  txMac->SendTxOpportunity (Seconds (0.1), 10);
   NS_TEST_ASSERT_MSG_EQ ("ABCDEFGH", txMac->GetDataReceived (), "Segmentation is not OK");
 
-  txMac->SendTxOpportunity (10);
+  txMac->SendTxOpportunity (Seconds (0.1), 10);
   NS_TEST_ASSERT_MSG_EQ ("IJKLMNOP", txMac->GetDataReceived (), "2 Segmentation is not OK");
 
-  txMac->SendTxOpportunity (10);
+  txMac->SendTxOpportunity (Seconds (0.1), 10);
   NS_TEST_ASSERT_MSG_EQ ("QRSTUVWX", txMac->GetDataReceived (), "3 Segmentation is not OK");
 
-  txMac->SendTxOpportunity (4);
+  txMac->SendTxOpportunity (Seconds (0.1), 4);
   NS_TEST_ASSERT_MSG_EQ ("YZ", txMac->GetDataReceived (), "4 Segmentation is not OK");
 
   Simulator::Destroy ();
@@ -216,217 +217,97 @@
   dataToSend = "STUVWXYZ";
   txPdcp->SendData (Seconds (0.0), dataToSend);
 
-  txMac->SendTxOpportunity (31);
+  txMac->SendTxOpportunity (Seconds (0.1), 31);
   NS_TEST_ASSERT_MSG_EQ ("ABCDEFGHIJKLMNOPQRSTUVWXYZ", txMac->GetDataReceived (), "Concatenation is not OK");
 
   Simulator::Destroy ();
 }
 
-/////////////////////////////////////////////////////////////////////
-
-TypeId
-LteTestMac::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::LteTestMac")
-    .SetParent<Object> ()
-    .AddConstructor<LteTestMac> ()
-    ;
-
-  return tid;
-}
-
-LteTestMac::LteTestMac ()
+/**
+ * Test 4.1.1.4 Report Buffer Status (test primitive parameters)
+ */
+LteRlcUmTransmitterReportBufferStatusTestCase::LteRlcUmTransmitterReportBufferStatusTestCase (std::string name)
+  : LteRlcUmTransmitterTestCase (name)
 {
-  NS_LOG_FUNCTION (this);
-  m_macSapProvider = new EnbMacMemberLteMacSapProvider<LteTestMac> (this);
-//   m_cmacSapProvider = new EnbMacMemberLteEnbCmacSapProvider (this);
-//   m_schedSapUser = new EnbMacMemberFfMacSchedSapUser (this);
-//   m_cschedSapUser = new EnbMacMemberFfMacCschedSapUser (this);
-//   m_enbPhySapUser = new EnbMacMemberLteEnbPhySapUser (this);
-}
-
-LteTestMac::~LteTestMac ()
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void
-LteTestMac::DoDispose ()
-{
-  NS_LOG_FUNCTION (this);
-  delete m_macSapProvider;
-//   delete m_cmacSapProvider;
-//   delete m_schedSapUser;
-//   delete m_cschedSapUser;
-//   delete m_enbPhySapUser;
-}
-
-void
-LteTestMac::SetLteMacSapUser (LteMacSapUser* s)
-{
-  m_macSapUser = s;
 }
 
-LteMacSapProvider*
-LteTestMac::GetLteMacSapProvider (void)
-{
-  return m_macSapProvider;
-}
-
-void
-LteTestMac::SetLteMacLoopback (Ptr<LteTestMac> s)
-{
-  m_macLoopback = s;
-}
-
-std::string
-LteTestMac::GetDataReceived (void)
-{
-  NS_LOG_FUNCTION (this);
-
-  return m_receivedData;
-}
-
-void
-LteTestMac::SendTxOpportunity (uint32_t bytes)
+LteRlcUmTransmitterReportBufferStatusTestCase::~LteRlcUmTransmitterReportBufferStatusTestCase ()
 {
-  NS_LOG_FUNCTION (this);
-  NS_LOG_LOGIC ("Bytes = " << bytes);
-
-  Simulator::Schedule (Seconds (0.0), &LteMacSapUser::NotifyTxOpportunity, m_macSapUser, bytes);
-  Simulator::Run ();
-}
-
-
-/**
- * MAC SAP
- */
-
-void
-LteTestMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params)
-{
-  NS_LOG_FUNCTION (this);
-
-  LteRlcHeader rlcHeader;
-
-  // Remove RLC header
-  params.pdu->RemoveHeader (rlcHeader);
-  NS_LOG_LOGIC ("RLC header: " << rlcHeader);
-
-  // Copy data to a string
-  uint32_t dataLen = params.pdu->GetSize ();
-  uint8_t *buf = new uint8_t[dataLen];
-  params.pdu->CopyData (buf, dataLen);
-  m_receivedData = std::string ((char *)buf, dataLen);
-
-  NS_LOG_LOGIC ("Data (" << dataLen << ") = " << m_receivedData);
-  delete [] buf;
 }
 
 void
-LteTestMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-/////////////////////////////////////////////////////////////////////
-
-TypeId
-LteTestPdcp::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::LteTestPdcp")
-    .SetParent<Object> ()
-    .AddConstructor<LteTestPdcp> ()
-    ;
-
-  return tid;
-}
-
-LteTestPdcp::LteTestPdcp ()
+LteRlcUmTransmitterReportBufferStatusTestCase::DoRun (void)
 {
-  NS_LOG_FUNCTION (this);
-  m_rlcSapUser = new LteRlcSpecificLteRlcSapUser<LteTestPdcp> (this);
-  Simulator::ScheduleNow (&LteTestPdcp::Start, this);
-}
+  // Create topology
+  LteRlcUmTransmitterTestCase::DoRun ();
+
+  // The tests...
+  std::string dataToSend;
+  std::string dataReceived;
+
+  //
+  // d) Test the parameters of the ReportBufferStatus primitive
+  //
+
+  txMac->SendTxOpportunity (Seconds (0.1), (2+2) + (10+6));
 
-LteTestPdcp::~LteTestPdcp ()
-{
-  NS_LOG_FUNCTION (this);
-}
+  // PDCP entity sends data
+  txPdcp->SendData (Seconds (1.0), "ABCDEFGHIJ"); // 10
+  txPdcp->SendData (Seconds (1.0), "KLMNOPQRS");  // 9
+  txPdcp->SendData (Seconds (1.0), "TUVWXYZ");    // 7
+
+  txMac->SendTxOpportunity (Seconds (0.1), (2+2) + (10+6));
+  NS_TEST_ASSERT_MSG_EQ ("ABCDEFGHIJKLMNOP",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  txPdcp->SendData (Seconds (1.0), "ABCDEFGH");     // 8
+  txPdcp->SendData (Seconds (1.0), "IJKLMNOPQRST"); // 12
+  txPdcp->SendData (Seconds (1.0), "UVWXYZ");       // 6
+
+  txMac->SendTxOpportunity (Seconds (0.1), 2 + 3);
+  NS_TEST_ASSERT_MSG_EQ ("QRS",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  txPdcp->SendData (Seconds (1.0), "ABCDEFGH");     // 8
+  txPdcp->SendData (Seconds (1.0), "IJKLMNOPQRST"); // 12
+  txPdcp->SendData (Seconds (1.0), "UVWXYZ");       // 6
 
-void
-LteTestPdcp::DoDispose ()
-{
-  NS_LOG_FUNCTION (this);
-  delete m_rlcSapUser;
-}
+  txPdcp->SendData (Seconds (1.0), "ABCDEFGHIJ");   // 10
+  txPdcp->SendData (Seconds (1.0), "KLMNOPQRST");   // 10
+  txPdcp->SendData (Seconds (1.0), "UVWXYZ");       // 6
+
+  txMac->SendTxOpportunity (Seconds (0.1), 2 + 7);
+  NS_TEST_ASSERT_MSG_EQ ("TUVWXYZ",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  txMac->SendTxOpportunity (Seconds (0.1), (2+2) + (8+2));
+  NS_TEST_ASSERT_MSG_EQ ("ABCDEFGHIJ",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  txPdcp->SendData (Seconds (1.0), "ABCDEFGHIJ");   // 10
+  txPdcp->SendData (Seconds (1.0), "KLMNOPQRST");   // 10
+  txPdcp->SendData (Seconds (1.0), "UVWXYZ");       // 6
 
-void
-LteTestPdcp::SetLteRlcSapProvider (LteRlcSapProvider* s)
-{
-  m_rlcSapProvider = s;
-}
+  txMac->SendTxOpportunity (Seconds (0.1), 2 + 2);
+  NS_TEST_ASSERT_MSG_EQ ("KL",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  txMac->SendTxOpportunity (Seconds (0.1), 2 + 3);
+  NS_TEST_ASSERT_MSG_EQ ("MNO",
+                         txMac->GetDataReceived (), "SDU is not OK");
 
-LteRlcSapUser*
-LteTestPdcp::GetLteRlcSapUser (void)
-{
-  return m_rlcSapUser;
+  txMac->SendTxOpportunity (Seconds (0.1), 2 + 5);
+  NS_TEST_ASSERT_MSG_EQ ("PQRST",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  txMac->SendTxOpportunity (Seconds (0.1), (2+2+1+2+1+2+1) + (6+8+12+6+10+10+3));
+  NS_TEST_ASSERT_MSG_EQ ("UVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  txMac->SendTxOpportunity (Seconds (0.1), (2+2+1+2) + (3+10+10+6));
+  NS_TEST_ASSERT_MSG_EQ ("XYZABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                         txMac->GetDataReceived (), "SDU is not OK");
+
+  Simulator::Destroy ();
 }
 
-
-std::string
-LteTestPdcp::GetDataReceived (void)
-{
-  NS_LOG_FUNCTION (this);
-
-  return m_receivedData;
-}
-
-
-/**
- * RLC SAP
- */
-
-void
-LteTestPdcp::DoReceivePdcpPdu (Ptr<Packet> p)
-{
-  NS_LOG_FUNCTION (this);
-  NS_LOG_LOGIC ("PDU received = " << (*p));
-
-  uint32_t dataLen = p->GetSize ();
-  uint8_t *buf = new uint8_t[dataLen];
-  p->CopyData (buf, dataLen);
-  m_receivedData = std::string ((char *)buf, dataLen);
-
-  NS_LOG_LOGIC (m_receivedData);
-
-  delete [] buf;
-}
-
-/**
- * START
- */
-
-void
-LteTestPdcp::Start ()
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void
-LteTestPdcp::SendData (Time at, std::string dataToSend)
-{
-  NS_LOG_FUNCTION (this);
-
-  LteRlcSapProvider::TransmitPdcpPduParameters p;
-  p.rnti = 111;
-  p.lcid = 222;
-
-  NS_LOG_LOGIC ("Data(" << dataToSend.length () << ") = " << dataToSend.data ());
-  p.pdcpPdu = Create<Packet> ((uint8_t *) dataToSend.data (), dataToSend.length ());
-
-  NS_LOG_LOGIC ("Packet(" << p.pdcpPdu->GetSize () << ")");
-  Simulator::Schedule (at, &LteRlcSapProvider::TransmitPdcpPdu, m_rlcSapProvider, p);
-  Simulator::Run ();
-}
-
--- a/src/lte/test/lte-test-rlc-um-transmitter.h	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/test/lte-test-rlc-um-transmitter.h	Wed Sep 28 14:12:44 2011 +0200
@@ -22,119 +22,13 @@
 #define LTE_TEST_RLC_UM_TRANSMITTER_H
 
 #include "ns3/test.h"
-#include "ns3/type-id.h"
 
-#include "ns3/lte-mac-sap.h"
-#include "ns3/lte-enb-mac.h"
-#include "ns3/lte-rlc-sap.h"
-
+#include "ns3/lte-test-entities.h"
 
 using namespace ns3;
 
 
 /**
- * This class implements a testing loopback MAC layer
- */
-class LteTestMac : public Object
-{
-//   friend class EnbMacMemberLteEnbCmacSapProvider;
-    friend class EnbMacMemberLteMacSapProvider<LteTestMac>;
-//   friend class EnbMacMemberFfMacSchedSapUser;
-//   friend class EnbMacMemberFfMacCschedSapUser;
-//   friend class EnbMacMemberLteEnbPhySapUser;
-
-  public:
-    static TypeId GetTypeId (void);
-
-    LteTestMac (void);
-    virtual ~LteTestMac (void);
-    virtual void DoDispose (void);
-
-    void SendTxOpportunity (uint32_t);
-    std::string GetDataReceived (void);
-
-    /**
-    * \brief Set the MAC SAP user
-    * \param s a pointer to the MAC SAP user
-    */
-    void SetLteMacSapUser (LteMacSapUser* s);
-    /**
-    * \brief Get the MAC SAP provider
-    * \return a pointer to the SAP provider of the MAC
-    */
-    LteMacSapProvider* GetLteMacSapProvider (void);
-
-    /**
-    * \brief Set the other side of the MAC Loopback
-    * \param s a pointer to the other side of the MAC loopback
-    */
-    void SetLteMacLoopback (Ptr<LteTestMac> s);
-
-  private:
-    // forwarded from LteMacSapProvider
-    void DoTransmitPdu (LteMacSapProvider::TransmitPduParameters);
-    void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters);
-
-    LteMacSapProvider* m_macSapProvider;
-    LteMacSapUser* m_macSapUser;
-    Ptr<LteTestMac> m_macLoopback;
-
-    std::string m_receivedData;
-
-};
-
-/////////////////////////////////////////////////////////////////////
-
-/**
- * This class implements a testing PDCP layer
- */
-class LteTestPdcp : public Object
-{
-    friend class LteRlcSpecificLteRlcSapUser<LteTestPdcp>;
-//   friend class EnbMacMemberLteEnbCmacSapProvider;
-//   friend class EnbMacMemberLteMacSapProvider<LteTestMac>;
-//   friend class EnbMacMemberFfMacSchedSapUser;
-//   friend class EnbMacMemberFfMacCschedSapUser;
-//   friend class EnbMacMemberLteEnbPhySapUser;
-
-  public:
-    static TypeId GetTypeId (void);
-
-    LteTestPdcp (void);
-    virtual ~LteTestPdcp (void);
-    virtual void DoDispose (void);
-
-
-    /**
-    * \brief Set the RLC SAP provider
-    * \param s a pointer to the RLC SAP provider
-    */
-    void SetLteRlcSapProvider (LteRlcSapProvider* s);
-    /**
-    * \brief Get the RLC SAP user
-    * \return a pointer to the SAP user of the RLC
-    */
-    LteRlcSapUser* GetLteRlcSapUser (void);
-
-    void Start ();
-
-    void SendData (Time at, std::string dataToSend);
-    std::string GetDataReceived (void);
-
-  private:
-    // Interface forwarded by LteRlcSapUser
-    virtual void DoReceivePdcpPdu (Ptr<Packet> p);
-
-    LteRlcSapUser* m_rlcSapUser;
-    LteRlcSapProvider* m_rlcSapProvider;
-
-    std::string m_receivedData;
-
-};
-
-/////////////////////////////////////////////////////////////////////
-
-/**
  * TestSuite 4.1.1 RLC UM: Only transmitter
  */
 class LteRlcUmTransmitterTestSuite : public TestSuite
@@ -204,4 +98,19 @@
 
 };
 
+/**
+ * Test 4.1.1.4 Report Buffer Status (test primitive parameters)
+ */
+class LteRlcUmTransmitterReportBufferStatusTestCase : public LteRlcUmTransmitterTestCase
+{
+  public:
+    LteRlcUmTransmitterReportBufferStatusTestCase (std::string name);
+    LteRlcUmTransmitterReportBufferStatusTestCase ();
+    virtual ~LteRlcUmTransmitterReportBufferStatusTestCase ();
+
+  private:
+    virtual void DoRun (void);
+
+};
+
 #endif /* LTE_TEST_RLC_UM_TRANSMITTER_H */
--- a/src/lte/wscript	Wed Sep 28 14:12:34 2011 +0200
+++ b/src/lte/wscript	Wed Sep 28 14:12:44 2011 +0200
@@ -26,6 +26,9 @@
         'model/lte-rlc-um.cc',
         'model/lte-rlc-tag.cc',
         'model/lte-rlc-sdu-status-tag.cc',
+        'model/lte-pdcp-sap.cc',
+        'model/lte-pdcp.cc',
+        'model/lte-pdcp-header.cc',
         'model/eps-bearer.cc',
         'model/lte-net-device.cc',
         'model/lte-enb-net-device.cc',
@@ -73,6 +76,7 @@
         'test/lte-test-pf-ff-mac-scheduler.cc',
         'test/lte-test-earfcn.cc',
         'test/lte-test-spectrum-value-helper.cc',
+        'test/lte-test-entities.cc',
         'test/lte-test-rlc-um-transmitter.cc',
         'test/epc-test-gtpu.cc',
         'test/test-eps-tft-classifier.cc',
@@ -103,6 +107,9 @@
         'model/lte-rlc-um.h',
         'model/lte-rlc-tag.h',
         'model/lte-rlc-sdu-status-tag.h',
+        'model/lte-pdcp-sap.h',
+        'model/lte-pdcp.h',
+        'model/lte-pdcp-header.h',
         'model/eps-bearer.h',
         'model/lte-net-device.h',
         'model/lte-enb-net-device.h',
@@ -143,7 +150,7 @@
         'test/lte-test-ue-phy.h',
         'test/lte-test-rr-ff-mac-scheduler.h',
         'test/lte-test-pf-ff-mac-scheduler.h',
-        'test/lte-test-pf-ff-mac-scheduler.h',
+        'test/lte-test-entities.h',
         'test/lte-test-rlc-um-transmitter.h',
         'test/epc-test-gtpu.h',
         'model/lte-tft.h',