diff --git a/src/lte/helper/lena-helper.cc b/src/lte/helper/lena-helper.cc index 67c62f154..ca1ad8850 100644 --- a/src/lte/helper/lena-helper.cc +++ b/src/lte/helper/lena-helper.cc @@ -111,6 +111,10 @@ LenaHelper::DoStart (void) m_rlcStats = CreateObject (); m_rlcStats->SetDlOutputFilename("DlRlcStats.csv"); m_rlcStats->SetUlOutputFilename("UlRlcStats.csv"); + m_pdcpStats = CreateObject (); + m_pdcpStats->SetDlOutputFilename("DlPdcpStats.csv"); + m_pdcpStats->SetUlOutputFilename("UlPdcpStats.csv"); + Object::DoStart (); } @@ -764,6 +768,7 @@ UlRxPduCallback (Ptr rlcStats, std::string path, rlcStats->UlRxPdu (cellId, imsi, rnti, lcid, packetSize, delay); } + void DlSchedulingCallback (Ptr macStats, std::string path, uint32_t frameNo, uint32_t subframeNo, @@ -877,4 +882,36 @@ LenaHelper::GetRlcStats (void) return m_rlcStats; } +void +LenaHelper::EnablePdcpTraces (void) +{ + EnableDlPdcpTraces (); + EnableUlPdcpTraces (); +} + +void +LenaHelper::EnableDlPdcpTraces (void) +{ + NS_LOG_FUNCTION_NOARGS (); + Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/UeMap/*/RadioBearerMap/*/LtePdcp/TxPDU", + MakeBoundCallback (&DlTxPduCallback, m_pdcpStats)); + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/RadioBearerMap/*/LtePdcp/RxPDU", + MakeBoundCallback (&DlRxPduCallback, m_pdcpStats)); +} + +void +LenaHelper::EnableUlPdcpTraces (void) +{ + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/RadioBearerMap/*/LtePdcp/TxPDU", + MakeBoundCallback (&UlTxPduCallback, m_pdcpStats)); + Config::Connect ("/NodeList/*/DeviceList/*/LteEnbRrc/UeMap/*/RadioBearerMap/*/LtePdcp/RxPDU", + MakeBoundCallback (&UlRxPduCallback, m_pdcpStats)); +} + +Ptr +LenaHelper::GetPdcpStats (void) +{ + return m_pdcpStats; +} + } // namespace ns3 diff --git a/src/lte/helper/lena-helper.h b/src/lte/helper/lena-helper.h index 6cf30d862..558e4186c 100644 --- a/src/lte/helper/lena-helper.h +++ b/src/lte/helper/lena-helper.h @@ -223,8 +223,33 @@ public: */ void SetTraceDirectory (std::string path); + /** + * + * \return the RLC stats calculator object + */ Ptr GetRlcStats (void); + /** + * Enable trace sinks for PDCP layer + */ + void EnablePdcpTraces (void); + + /** + * Enable trace sinks for DL PDCP layer + */ + void EnableDlPdcpTraces (void); + + /** + * Enable trace sinks for UL MAC layer + */ + void EnableUlPdcpTraces (void); + + /** + * + * \return the PDCP stats calculator object + */ + Ptr GetPdcpStats (void); + protected: // inherited from Object virtual void DoStart (void); @@ -253,6 +278,8 @@ private: Ptr m_macStats; Ptr m_rlcStats; + Ptr m_pdcpStats; + enum LteEpsBearerToRlcMapping_t {RLC_SM_ALWAYS = 1, RLC_UM_ALWAYS = 2, RLC_AM_ALWAYS = 3, diff --git a/src/lte/model/lte-pdcp-tag.cc b/src/lte/model/lte-pdcp-tag.cc new file mode 100644 index 000000000..c601d61dc --- /dev/null +++ b/src/lte/model/lte-pdcp-tag.cc @@ -0,0 +1,88 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 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: Jaume Nin + * Nicola Baldo + */ + +#include "lte-pdcp-tag.h" +#include "ns3/tag.h" +#include "ns3/uinteger.h" + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (PdcpTag); + +PdcpTag::PdcpTag () + : m_senderTimestamp (Seconds (0)) +{ + // Nothing to do here +} + + +PdcpTag::PdcpTag (Time senderTimestamp) + : m_senderTimestamp (senderTimestamp) + +{ + // Nothing to do here +} + +TypeId +PdcpTag::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::PdcpTag") + .SetParent () + .AddConstructor (); + return tid; +} + +TypeId +PdcpTag::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +uint32_t +PdcpTag::GetSerializedSize (void) const +{ + return sizeof(Time); +} + +void +PdcpTag::Serialize (TagBuffer i) const +{ + int64_t senderTimestamp = m_senderTimestamp.GetNanoSeconds (); + i.Write ((const uint8_t *)&senderTimestamp, sizeof(int64_t)); +} + +void +PdcpTag::Deserialize (TagBuffer i) +{ + int64_t senderTimestamp; + i.Read ((uint8_t *)&senderTimestamp, 8); + m_senderTimestamp = NanoSeconds (senderTimestamp); + +} + +void +PdcpTag::Print (std::ostream &os) const +{ + os << m_senderTimestamp; +} + +} // namespace ns3 + diff --git a/src/lte/model/lte-pdcp-tag.h b/src/lte/model/lte-pdcp-tag.h new file mode 100644 index 000000000..9f13bd90f --- /dev/null +++ b/src/lte/model/lte-pdcp-tag.h @@ -0,0 +1,81 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2011 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: Jaume Nin + * Nicola Baldo + */ + +#ifndef PDCP_TAG_H +#define PDCP_TAG_H + +#include "ns3/packet.h" +#include "ns3/nstime.h" + + +namespace ns3 { + +class Tag; + +/** + * Tag to calculate the per-PDU delay from eNb PDCP to UE PDCP + */ + +class PdcpTag : public Tag +{ +public: + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + + /** + * Create an empty PDCP tag + */ + PdcpTag (); + /** + * Create an PDCP tag with the given senderTimestamp + */ + PdcpTag (Time senderTimestamp); + + virtual void Serialize (TagBuffer i) const; + virtual void Deserialize (TagBuffer i); + virtual uint32_t GetSerializedSize () const; + virtual void Print (std::ostream &os) const; + + /** + * Get the instant when the PDCP delivers the PDU to the MAC SAP provider + */ + Time GetSenderTimestamp (void) const + { + return m_senderTimestamp; + } + + /** + * Set the sender timestamp + * @param senderTimestamp time stamp of the instant when the PDCP delivers the PDU to the MAC SAP provider + */ + void SetSenderTimestamp (Time senderTimestamp) + { + this->m_senderTimestamp = senderTimestamp; + } + +private: + Time m_senderTimestamp; + +}; + +} //namespace ns3 + +#endif /* PDCP_TAG_H */ diff --git a/src/lte/model/lte-pdcp.cc b/src/lte/model/lte-pdcp.cc index b7e03a33b..566dfa41d 100644 --- a/src/lte/model/lte-pdcp.cc +++ b/src/lte/model/lte-pdcp.cc @@ -24,6 +24,7 @@ #include "ns3/lte-pdcp.h" #include "ns3/lte-pdcp-header.h" #include "ns3/lte-pdcp-sap.h" +#include "ns3/lte-pdcp-tag.h" NS_LOG_COMPONENT_DEFINE ("LtePdcp"); @@ -162,11 +163,15 @@ LtePdcp::DoTransmitRrcPdu (Ptr p) NS_LOG_LOGIC ("PDCP header: " << pdcpHeader); p->AddHeader (pdcpHeader); + PdcpTag pdcpTag (Simulator::Now ()); + p->AddPacketTag (pdcpTag); + LteRlcSapProvider::TransmitPdcpPduParameters params; params.rnti = m_rnti; params.lcid = m_lcid; params.pdcpPdu = p; + m_txPdu (m_rnti, m_lcid, p->GetSize ()); m_rlcSapProvider->TransmitPdcpPdu (params); } @@ -179,11 +184,23 @@ LtePdcp::DoReceivePdu (Ptr p) p->RemoveHeader (pdcpHeader); NS_LOG_LOGIC ("PDCP header: " << pdcpHeader); + PdcpTag pdcpTag; + Time delay; + if (p->FindFirstMatchingByteTag(pdcpTag)) + { + delay = Simulator::Now() - pdcpTag.GetSenderTimestamp (); + } + else + { + NS_LOG_WARN (this << " could not find PdcpTag"); + } + m_rxSequenceNumber = pdcpHeader.GetSequenceNumber () + 1; if (m_rxSequenceNumber > m_maxPdcpSn) { m_rxSequenceNumber = 0; } + m_rxPdu(m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds ()); LtePdcpSapUser::ReceiveRrcPduParameters params; params.rrcPdu = p; params.rnti = m_rnti; diff --git a/src/lte/model/lte-pdcp.h b/src/lte/model/lte-pdcp.h index 0fe4475f5..89bdcb0d7 100644 --- a/src/lte/model/lte-pdcp.h +++ b/src/lte/model/lte-pdcp.h @@ -105,11 +105,13 @@ protected: uint8_t m_lcid; /** - * Used to inform of a PDU delivery to the RLC SAP provider + * Used to inform of a PDU delivery to the RLC SAP provider. + * The parameters are RNTI, LCID and bytes delivered */ TracedCallback m_txPdu; /** - * Used to inform of a PDU reception from the RLC SAP user + * Used to inform of a PDU reception from the RLC SAP user. + * The parameters are RNTI, LCID, bytes delivered and delivery delay in nanoseconds. */ TracedCallback m_rxPdu; diff --git a/src/lte/test/test-lte-epc-e2e-data.cc b/src/lte/test/test-lte-epc-e2e-data.cc index 4c4e73bf6..a0c18c6e8 100644 --- a/src/lte/test/test-lte-epc-e2e-data.cc +++ b/src/lte/test/test-lte-epc-e2e-data.cc @@ -234,6 +234,10 @@ LteEpcE2eDataTestCase::DoRun () } + lteHelper->EnableRlcTraces (); + lteHelper->EnableMacTraces (); + lteHelper->EnablePdcpTraces (); + Simulator::Stop (Seconds (2.0)); Simulator::Run (); diff --git a/src/lte/wscript b/src/lte/wscript index 0c40308f3..444395f63 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -23,6 +23,7 @@ def build(bld): 'model/lte-pdcp-sap.cc', 'model/lte-pdcp.cc', 'model/lte-pdcp-header.cc', + 'model/lte-pdcp-tag.cc', 'model/eps-bearer.cc', 'model/lte-radio-bearer-info.cc', 'model/lte-net-device.cc', @@ -105,6 +106,7 @@ def build(bld): 'model/lte-pdcp-sap.h', 'model/lte-pdcp.h', 'model/lte-pdcp-header.h', + 'model/lte-pdcp-tag.h', 'model/eps-bearer.h', 'model/lte-radio-bearer-info.h', 'model/lte-net-device.h',