diff --git a/src/lte/model/lte-pdcp-header.cc b/src/lte/model/lte-pdcp-header.cc new file mode 100644 index 000000000..8b2689121 --- /dev/null +++ b/src/lte/model/lte-pdcp-header.cc @@ -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 + */ + +#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
() + .AddConstructor () + ; + 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 diff --git a/src/lte/model/lte-pdcp-header.h b/src/lte/model/lte-pdcp-header.h new file mode 100644 index 000000000..6c156dd76 --- /dev/null +++ b/src/lte/model/lte-pdcp-header.h @@ -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 + */ + +#ifndef LTE_PDCP_HEADER_H +#define LTE_PDCP_HEADER_H + +#include "ns3/header.h" + +#include + +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 diff --git a/src/lte/model/lte-pdcp.cc b/src/lte/model/lte-pdcp.cc new file mode 100644 index 000000000..1d1f2080c --- /dev/null +++ b/src/lte/model/lte-pdcp.cc @@ -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 + */ + +#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 p); + +private: + LtePdcpSpecificLteRlcSapUser (); + LtePdcp* m_pdcp; +}; + +LtePdcpSpecificLteRlcSapUser::LtePdcpSpecificLteRlcSapUser (LtePdcp* pdcp) + : m_pdcp (pdcp) +{ +} + +LtePdcpSpecificLteRlcSapUser::LtePdcpSpecificLteRlcSapUser () +{ +} + +void +LtePdcpSpecificLteRlcSapUser::ReceivePdcpPdu (Ptr 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 (this); + m_rlcSapUser = new LtePdcpSpecificLteRlcSapUser (this); + + Simulator::ScheduleNow (&LtePdcp::Start, this); +} + +TypeId +LtePdcp::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::LtePdcp") + .SetParent () + .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 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 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 diff --git a/src/lte/model/lte-pdcp.h b/src/lte/model/lte-pdcp.h new file mode 100644 index 000000000..0fe4475f5 --- /dev/null +++ b/src/lte/model/lte-pdcp.h @@ -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 + */ + +#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 +{ + friend class LtePdcpSpecificLteRlcSapUser; + friend class LtePdcpSpecificLtePdcpSapProvider; +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 p); + + LtePdcpSapUser* m_pdcpSapUser; + LtePdcpSapProvider* m_pdcpSapProvider; + + // Interface provided to lower RLC entity + virtual void DoReceivePdu (Ptr 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 m_txPdu; + /** + * Used to inform of a PDU reception from the RLC SAP user + */ + TracedCallback 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 diff --git a/src/lte/model/lte-rlc-header.cc b/src/lte/model/lte-rlc-header.cc index 130714c72..d4c292500 100644 --- a/src/lte/model/lte-rlc-header.cc +++ b/src/lte/model/lte-rlc-header.cc @@ -131,17 +131,31 @@ void LteRlcHeader::Print (std::ostream &os) const { std::list ::const_iterator it1 = m_extensionBits.begin (); std::list ::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(" << i << ")=" << (uint16_t)(*it1); - os << " LI(" << i << ")=" << (uint16_t)(*it2); + os << " E="; + } + while ( it1 != m_extensionBits.end () ) + { + os << (uint16_t)(*it1); + it1++; + } + + if (it2 != m_lengthIndicators.end ()) + { + os << " LI="; + } + while ( it2 != m_lengthIndicators.end () ) + { + os << (uint16_t)(*it2) << " "; + it2++; } } diff --git a/src/lte/model/lte-rlc-tag.h b/src/lte/model/lte-rlc-tag.h index 525d2a513..ac189ffec 100644 --- a/src/lte/model/lte-rlc-tag.h +++ b/src/lte/model/lte-rlc-tag.h @@ -56,7 +56,7 @@ public: /** * 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 @@ public: * 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; } diff --git a/src/lte/model/lte-rlc-um.cc b/src/lte/model/lte-rlc-um.cc index 5b10bff11..5c8fa54fe 100644 --- a/src/lte/model/lte-rlc-um.cc +++ b/src/lte/model/lte-rlc-um.cc @@ -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 @@ namespace ns3 { 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 @@ LteRlcUm::DoTransmitPdcpPdu (Ptr p) { 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 @@ LteRlcUm::DoNotifyTxOpportunity (uint32_t bytes) 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 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 @@ LteRlcUm::DoNotifyTxOpportunity (uint32_t bytes) // 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 @@ LteRlcUm::DoNotifyTxOpportunity (uint32_t bytes) // (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 ); } } diff --git a/src/lte/model/lte-rlc-um.h b/src/lte/model/lte-rlc-um.h index 3c3ddcbea..073113c2d 100644 --- a/src/lte/model/lte-rlc-um.h +++ b/src/lte/model/lte-rlc-um.h @@ -68,6 +68,7 @@ private: void ReassembleAndDeliver (Ptr packet); private: + uint32_t m_txBufferSize; std::vector < Ptr > m_txBuffer; // Transmission buffer std::map > m_rxBuffer; // Reception buffer std::vector < Ptr > m_reasBuffer; // Reassembling buffer diff --git a/src/lte/model/lte-rlc.cc b/src/lte/model/lte-rlc.cc index 5f19a5a7a..f5ee441ff 100644 --- a/src/lte/model/lte-rlc.cc +++ b/src/lte/model/lte-rlc.cc @@ -109,9 +109,9 @@ TypeId LteRlc::GetTypeId (void) } 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 @@ LteRlcSm::DoReceivePdu (Ptr p) 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 () ); diff --git a/src/lte/model/lte-rlc.h b/src/lte/model/lte-rlc.h index b00a63628..8f59c30d5 100644 --- a/src/lte/model/lte-rlc.h +++ b/src/lte/model/lte-rlc.h @@ -61,7 +61,7 @@ public: * * \param rnti */ - void SetRnti (uint8_t rnti); + void SetRnti (uint16_t rnti); /** * diff --git a/src/lte/test/lte-test-entities.cc b/src/lte/test/lte-test-entities.cc new file mode 100644 index 000000000..63d8ec04e --- /dev/null +++ b/src/lte/test/lte-test-entities.cc @@ -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 + */ + +#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 () + .AddConstructor () + ; + + return tid; +} + +LteTestRrc::LteTestRrc () +{ + NS_LOG_FUNCTION (this); + m_pdcpSapUser = new LtePdcpSpecificLtePdcpSapUser (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 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 ((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 () + .AddConstructor () + ; + + return tid; +} + +LteTestPdcp::LteTestPdcp () +{ + NS_LOG_FUNCTION (this); + m_rlcSapUser = new LteRlcSpecificLteRlcSapUser (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 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 ((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 () + .AddConstructor () + ; + + return tid; +} + +LteTestMac::LteTestMac () +{ + NS_LOG_FUNCTION (this); + m_macSapProvider = new EnbMacMemberLteMacSapProvider (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 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 + } +} diff --git a/src/lte/test/lte-test-entities.h b/src/lte/test/lte-test-entities.h new file mode 100644 index 000000000..9f03c2bd1 --- /dev/null +++ b/src/lte/test/lte-test-entities.h @@ -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 + */ + +#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; +// friend class EnbMacMemberLteEnbCmacSapProvider; +// friend class EnbMacMemberLteMacSapProvider; +// 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 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; +// friend class EnbMacMemberLteEnbCmacSapProvider; +// friend class EnbMacMemberLteMacSapProvider; +// 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 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; +// 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 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 m_macLoopback; + + std::string m_receivedData; + + bool m_pdcpHeaderPresent; + bool m_txOpportunityMode; + +}; + +#endif /* LTE_TEST_MAC_H */ diff --git a/src/lte/test/lte-test-rlc-um-transmitter.cc b/src/lte/test/lte-test-rlc-um-transmitter.cc index d45c45168..7896d17f2 100644 --- a/src/lte/test/lte-test-rlc-um-transmitter.cc +++ b/src/lte/test/lte-test-rlc-um-transmitter.cc @@ -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 @@ LteRlcUmTransmitterTestSuite::LteRlcUmTransmitterTestSuite () AddTestCase (new LteRlcUmTransmitterOneSduTestCase ("One SDU, one PDU")); AddTestCase (new LteRlcUmTransmitterSegmentationTestCase ("Segmentation")); AddTestCase (new LteRlcUmTransmitterConcatenationTestCase ("Concatenation")); + AddTestCase (new LteRlcUmTransmitterReportBufferStatusTestCase ("ReportBufferStatus primitive")); } @@ -68,12 +68,13 @@ LteRlcUmTransmitterTestCase::DoRun (void) { 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 @@ LteRlcUmTransmitterOneSduTestCase::DoRun (void) 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 @@ LteRlcUmTransmitterSegmentationTestCase::DoRun (void) 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 @@ LteRlcUmTransmitterConcatenationTestCase::DoRun (void) 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 () - .AddConstructor () - ; - - return tid; -} - -LteTestMac::LteTestMac () -{ - NS_LOG_FUNCTION (this); - m_macSapProvider = new EnbMacMemberLteMacSapProvider (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 s) -{ - m_macLoopback = s; -} - -std::string -LteTestMac::GetDataReceived (void) -{ - NS_LOG_FUNCTION (this); - - return m_receivedData; -} - -void -LteTestMac::SendTxOpportunity (uint32_t bytes) -{ - NS_LOG_FUNCTION (this); - NS_LOG_LOGIC ("Bytes = " << bytes); - - Simulator::Schedule (Seconds (0.0), &LteMacSapUser::NotifyTxOpportunity, m_macSapUser, bytes); - Simulator::Run (); -} - - /** - * MAC SAP + * Test 4.1.1.4 Report Buffer Status (test primitive parameters) */ - -void -LteTestMac::DoTransmitPdu (LteMacSapProvider::TransmitPduParameters params) +LteRlcUmTransmitterReportBufferStatusTestCase::LteRlcUmTransmitterReportBufferStatusTestCase (std::string name) + : LteRlcUmTransmitterTestCase (name) { - 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; +LteRlcUmTransmitterReportBufferStatusTestCase::~LteRlcUmTransmitterReportBufferStatusTestCase () +{ } void -LteTestMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params) +LteRlcUmTransmitterReportBufferStatusTestCase::DoRun (void) { - NS_LOG_FUNCTION (this); -} - -///////////////////////////////////////////////////////////////////// - -TypeId -LteTestPdcp::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::LteTestPdcp") - .SetParent () - .AddConstructor () - ; - - return tid; -} - -LteTestPdcp::LteTestPdcp () -{ - NS_LOG_FUNCTION (this); - m_rlcSapUser = new LteRlcSpecificLteRlcSapUser (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 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 ((uint8_t *) dataToSend.data (), dataToSend.length ()); - - NS_LOG_LOGIC ("Packet(" << p.pdcpPdu->GetSize () << ")"); - Simulator::Schedule (at, &LteRlcSapProvider::TransmitPdcpPdu, m_rlcSapProvider, p); - Simulator::Run (); + // 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)); + + // 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 + + 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 + + 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"); + + 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 (); } diff --git a/src/lte/test/lte-test-rlc-um-transmitter.h b/src/lte/test/lte-test-rlc-um-transmitter.h index 8f2ab728a..a3f17140c 100644 --- a/src/lte/test/lte-test-rlc-um-transmitter.h +++ b/src/lte/test/lte-test-rlc-um-transmitter.h @@ -22,118 +22,12 @@ #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; -// 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 s); - - private: - // forwarded from LteMacSapProvider - void DoTransmitPdu (LteMacSapProvider::TransmitPduParameters); - void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters); - - LteMacSapProvider* m_macSapProvider; - LteMacSapUser* m_macSapUser; - Ptr m_macLoopback; - - std::string m_receivedData; - -}; - -///////////////////////////////////////////////////////////////////// - -/** - * This class implements a testing PDCP layer - */ -class LteTestPdcp : public Object -{ - friend class LteRlcSpecificLteRlcSapUser; -// friend class EnbMacMemberLteEnbCmacSapProvider; -// friend class EnbMacMemberLteMacSapProvider; -// 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 p); - - LteRlcSapUser* m_rlcSapUser; - LteRlcSapProvider* m_rlcSapProvider; - - std::string m_receivedData; - -}; - -///////////////////////////////////////////////////////////////////// - /** * TestSuite 4.1.1 RLC UM: Only transmitter */ @@ -204,4 +98,19 @@ class LteRlcUmTransmitterConcatenationTestCase : public LteRlcUmTransmitterTestC }; +/** + * 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 */ diff --git a/src/lte/wscript b/src/lte/wscript index 028d2eb9c..f6ee4945b 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -26,6 +26,9 @@ def build(bld): '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 @@ def build(bld): '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 @@ def build(bld): '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 @@ def build(bld): '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',