diff --git a/src/lte/helper/lena-helper.cc b/src/lte/helper/lena-helper.cc index 044f82d4e..cb9587af0 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/helper/rlc-stats-calculator.cc b/src/lte/helper/rlc-stats-calculator.cc index f1632228a..f81b2c888 100644 --- a/src/lte/helper/rlc-stats-calculator.cc +++ b/src/lte/helper/rlc-stats-calculator.cc @@ -131,7 +131,7 @@ RlcStatsCalculator::UlRxPdu (uint16_t cellId, uint64_t imsi, uint16_t rnti, Uint64StatsMap::iterator it = m_ulDelay.find (p); if (it == m_ulDelay.end ()) { - NS_LOG_DEBUG (this << " Creating UL stats calculators for IMSI " << p.m_imsi << " and LCI " << (uint32_t) p.m_lcId ); + NS_LOG_DEBUG (this << " Creating UL stats calculators for IMSI " << p.m_imsi << " and LCID " << (uint32_t) p.m_lcId ); m_ulDelay[p] = CreateObject > (); m_ulPduSize[p] = CreateObject > (); } @@ -156,7 +156,7 @@ RlcStatsCalculator::DlRxPdu (uint64_t imsi, uint16_t rnti, Uint64StatsMap::iterator it = m_dlDelay.find (p); if (it == m_dlDelay.end ()) { - NS_LOG_DEBUG (this << " Creating DL stats calculators for IMSI " << p.m_imsi << " and LCI " << (uint32_t) p.m_lcId ); + NS_LOG_DEBUG (this << " Creating DL stats calculators for IMSI " << p.m_imsi << " and LCID " << (uint32_t) p.m_lcId ); m_dlDelay[p] = CreateObject > (); m_dlPduSize[p] = CreateObject > (); } @@ -229,6 +229,8 @@ RlcStatsCalculator::ShowResults (void) void RlcStatsCalculator::WriteUlResults (std::ofstream& outFile) { + NS_LOG_FUNCTION (this); + // Get the unique IMSI / LCID list std::vector pairVector; @@ -276,6 +278,8 @@ RlcStatsCalculator::WriteUlResults (std::ofstream& outFile) void RlcStatsCalculator::WriteDlResults (std::ofstream& outFile) { + NS_LOG_FUNCTION (this); + // Get the unique IMSI list std::vector pairVector; for (Uint32Map::iterator it = m_dlTxPackets.begin (); it @@ -322,6 +326,8 @@ RlcStatsCalculator::WriteDlResults (std::ofstream& outFile) void RlcStatsCalculator::ResetResults (void) { + NS_LOG_FUNCTION (this); + m_ulTxPackets.erase (m_ulTxPackets.begin (), m_ulTxPackets.end ()); m_ulRxPackets.erase (m_ulRxPackets.begin (), m_ulRxPackets.end ()); m_ulRxData.erase (m_ulRxData.begin (), m_ulRxData.end ()); @@ -340,6 +346,8 @@ RlcStatsCalculator::ResetResults (void) void RlcStatsCalculator::CheckEpoch (bool forceEpoch) { + NS_LOG_FUNCTION (this); + if (Simulator::Now () > m_startTime + m_epochDuration /*|| forceEpoch == true*/) { ShowResults (); @@ -352,12 +360,14 @@ RlcStatsCalculator::CheckEpoch (bool forceEpoch) void RlcStatsCalculator::StartEpoch (void) { + NS_LOG_FUNCTION (this); m_startTime += m_epochDuration; } uint32_t RlcStatsCalculator::GetUlTxPackets (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_ulTxPackets[p]; } @@ -365,6 +375,7 @@ RlcStatsCalculator::GetUlTxPackets (uint64_t imsi, uint8_t lcid) uint32_t RlcStatsCalculator::GetUlRxPackets (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_ulRxPackets[p]; } @@ -372,6 +383,7 @@ RlcStatsCalculator::GetUlRxPackets (uint64_t imsi, uint8_t lcid) uint64_t RlcStatsCalculator::GetUlTxData (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_ulTxData[p]; } @@ -379,6 +391,7 @@ RlcStatsCalculator::GetUlTxData (uint64_t imsi, uint8_t lcid) uint64_t RlcStatsCalculator::GetUlRxData (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_ulRxData[p]; } @@ -386,11 +399,12 @@ RlcStatsCalculator::GetUlRxData (uint64_t imsi, uint8_t lcid) double RlcStatsCalculator::GetUlDelay (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); Uint64StatsMap::iterator it = m_ulDelay.find (p); if (it == m_ulDelay.end ()) { - NS_LOG_ERROR ("UL delay for " << imsi << " - " << lcid << " not found"); + NS_LOG_ERROR ("UL delay for " << imsi << " - " << (uint16_t) lcid << " not found"); return 0; } @@ -400,12 +414,13 @@ RlcStatsCalculator::GetUlDelay (uint64_t imsi, uint8_t lcid) std::vector RlcStatsCalculator::GetUlDelayStats (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); std::vector stats; Uint64StatsMap::iterator it = m_ulDelay.find (p); if (it == m_ulDelay.end ()) { - NS_LOG_ERROR ("UL delay for " << imsi << " - " << lcid << " not found"); + NS_LOG_ERROR ("UL delay for " << imsi << " - " << (uint16_t) lcid << " not found"); return stats; } @@ -419,12 +434,13 @@ RlcStatsCalculator::GetUlDelayStats (uint64_t imsi, uint8_t lcid) std::vector RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); std::vector stats; Uint32StatsMap::iterator it = m_ulPduSize.find (p); if (it == m_ulPduSize.end ()) { - NS_LOG_ERROR ("UL PDU Size for " << imsi << " - " << lcid << " not found"); + NS_LOG_ERROR ("UL PDU Size for " << imsi << " - " << (uint16_t) lcid << " not found"); return stats; } @@ -438,6 +454,7 @@ RlcStatsCalculator::GetUlPduSizeStats (uint64_t imsi, uint8_t lcid) uint32_t RlcStatsCalculator::GetDlTxPackets (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_dlTxPackets[p]; } @@ -445,6 +462,7 @@ RlcStatsCalculator::GetDlTxPackets (uint64_t imsi, uint8_t lcid) uint32_t RlcStatsCalculator::GetDlRxPackets (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_dlRxPackets[p]; } @@ -452,6 +470,7 @@ RlcStatsCalculator::GetDlRxPackets (uint64_t imsi, uint8_t lcid) uint64_t RlcStatsCalculator::GetDlTxData (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_dlTxData[p]; } @@ -459,6 +478,7 @@ RlcStatsCalculator::GetDlTxData (uint64_t imsi, uint8_t lcid) uint64_t RlcStatsCalculator::GetDlRxData (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_dlRxData[p]; } @@ -466,6 +486,7 @@ RlcStatsCalculator::GetDlRxData (uint64_t imsi, uint8_t lcid) uint32_t RlcStatsCalculator::GetUlCellId (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_ulCellId[p]; } @@ -473,6 +494,7 @@ RlcStatsCalculator::GetUlCellId (uint64_t imsi, uint8_t lcid) uint32_t RlcStatsCalculator::GetDlCellId (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); return m_dlCellId[p]; } @@ -480,6 +502,7 @@ RlcStatsCalculator::GetDlCellId (uint64_t imsi, uint8_t lcid) double RlcStatsCalculator::GetDlDelay (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); Uint64StatsMap::iterator it = m_dlDelay.find (p); if (it == m_dlDelay.end ()) @@ -493,6 +516,7 @@ RlcStatsCalculator::GetDlDelay (uint64_t imsi, uint8_t lcid) std::vector RlcStatsCalculator::GetDlDelayStats (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); std::vector stats; Uint64StatsMap::iterator it = m_dlDelay.find (p); @@ -513,6 +537,7 @@ RlcStatsCalculator::GetDlDelayStats (uint64_t imsi, uint8_t lcid) std::vector RlcStatsCalculator::GetDlPduSizeStats (uint64_t imsi, uint8_t lcid) { + NS_LOG_FUNCTION (this << imsi << (uint16_t) lcid); ImsiLcidPair_t p (imsi, lcid); std::vector stats; Uint32StatsMap::iterator it = m_dlPduSize.find (p); diff --git a/src/lte/model/eps-tft-classifier.cc b/src/lte/model/eps-tft-classifier.cc index 30b4c3b7a..1ce2e0b6e 100644 --- a/src/lte/model/eps-tft-classifier.cc +++ b/src/lte/model/eps-tft-classifier.cc @@ -67,7 +67,7 @@ EpsTftClassifier::Delete (uint32_t id) uint32_t EpsTftClassifier::Classify (Ptr p, LteTft::Direction direction) { - NS_LOG_FUNCTION (this << *p << direction); + NS_LOG_FUNCTION (this << p << direction); Ptr pCopy = p->Copy (); @@ -139,7 +139,7 @@ EpsTftClassifier::Classify (Ptr p, LteTft::Direction direction) << " remoteAddr=" << remoteAddress << " localPort=" << localPort << " remotePort=" << remotePort - << " tos=0x" << std::hex << tos); + << " tos=0x" << (uint16_t) tos ); // now it is possible to classify the packet! // we use a reverse iterator since filter priority is not implemented properly. 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/model/lte-tft.cc b/src/lte/model/lte-tft.cc index bcdae983a..3733979f5 100644 --- a/src/lte/model/lte-tft.cc +++ b/src/lte/model/lte-tft.cc @@ -59,8 +59,8 @@ std::ostream& operator<< (std::ostream& os, LteTft::PacketFilter& f) << " remotePortEnd: " << f.remotePortEnd << " localPortStart: " << f.localPortStart << " localPortEnd: " << f.localPortEnd - << " typeOfService: 0x" << std::hex << (uint16_t) f.typeOfService - << " typeOfServiceMask: 0x" << std::hex << (uint16_t) f.typeOfServiceMask; + << " typeOfService: 0x" << std::hex << (uint16_t) f.typeOfService << std::dec + << " typeOfServiceMask: 0x" << std::hex << (uint16_t) f.typeOfServiceMask << std::dec; return os; } @@ -72,7 +72,8 @@ LteTft::PacketFilter::PacketFilter () remotePortStart (0), remotePortEnd (65535), localPortStart (0), - localPortEnd (65535), + localPortEnd (65535), + typeOfService (0), typeOfServiceMask (0) { NS_LOG_FUNCTION (this); @@ -86,7 +87,7 @@ LteTft::PacketFilter::Matches (Direction d, uint16_t lp, uint8_t tos) { - NS_LOG_FUNCTION (this << d << ra << la << rp << lp << tos); + NS_LOG_FUNCTION (this << d << ra << la << rp << lp << (uint16_t) tos); if (d & direction) { NS_LOG_LOGIC ("d matches"); @@ -130,7 +131,7 @@ LteTft::PacketFilter::Matches (Direction d, } else { - NS_LOG_LOGIC ("d doesn't match: d=0x" << std::hex << d << " f.d=0x" << std::hex << direction); + NS_LOG_LOGIC ("d doesn't match: d=0x" << std::hex << d << " f.d=0x" << std::hex << direction << std::dec); } return false; } @@ -177,7 +178,7 @@ LteTft::Matches (Direction direction, uint16_t localPort, uint8_t typeOfService) { - NS_LOG_FUNCTION (this << direction << remoteAddress << localAddress << remotePort << localPort << typeOfService); + NS_LOG_FUNCTION (this << direction << remoteAddress << localAddress << std::dec << remotePort << localPort << (uint16_t) typeOfService); for (std::list::iterator it = m_filters.begin (); it != m_filters.end (); ++it) diff --git a/src/lte/test/test-eps-tft-classifier.cc b/src/lte/test/test-eps-tft-classifier.cc index aa645ed54..b53bf9eda 100644 --- a/src/lte/test/test-eps-tft-classifier.cc +++ b/src/lte/test/test-eps-tft-classifier.cc @@ -190,6 +190,19 @@ EpsTftClassifierTestSuite::EpsTftClassifierTestSuite () pf1_2_2.localPortEnd = 3489; tft1_2->Add (pf1_2_2); + + LteTft::PacketFilter pf1_2_3; + pf1_2_3.localPortStart = 7895; + pf1_2_3.localPortEnd = 7895; + tft1_2->Add (pf1_2_3); + + + LteTft::PacketFilter pf1_2_4; + pf1_2_4.remotePortStart = 5897; + pf1_2_4.remotePortEnd = 5897; + tft1_2->Add (pf1_2_4); + + c1->Add (tft1_2, 2); // ------------------------------------classifier---direction--------------src address---------------dst address---src port--dst port--ToS--TFT id @@ -218,7 +231,10 @@ EpsTftClassifierTestSuite::EpsTftClassifierTestSuite () AddTestCase (new EpsTftClassifierTestCase (c1, LteTft::UPLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 3456, 6, 0, 2)); AddTestCase (new EpsTftClassifierTestCase (c1, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 3461, 3461, 0, 2)); AddTestCase (new EpsTftClassifierTestCase (c1, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 9, 3489, 0, 2)); - + AddTestCase (new EpsTftClassifierTestCase (c1, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 9, 7895, 0, 2)); + AddTestCase (new EpsTftClassifierTestCase (c1, LteTft::UPLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 7895, 10, 0, 2)); + AddTestCase (new EpsTftClassifierTestCase (c1, LteTft::UPLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 9, 5897, 0, 2)); + AddTestCase (new EpsTftClassifierTestCase (c1, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 5897, 10, 0, 2)); /////////////////////////// @@ -294,6 +310,24 @@ EpsTftClassifierTestSuite::EpsTftClassifierTestSuite () AddTestCase (new EpsTftClassifierTestCase (c3, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 9, 3489, 0, 3)); + + /////////////////////////////////////////// + // check two TFTs with different ports + /////////////////////////////////////////// + + Ptr c4 = Create (); + Ptr tft4_1 = Create (); + tft4_1->Add (pf1_2_3); + c4->Add (tft4_1, 1); + Ptr tft4_2 = Create (); + tft4_2->Add (pf1_2_4); + c4->Add (tft4_2, 2); + AddTestCase (new EpsTftClassifierTestCase (c4, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 9, 3489, 0, 0)); + AddTestCase (new EpsTftClassifierTestCase (c4, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 9, 7895, 0, 1)); + AddTestCase (new EpsTftClassifierTestCase (c4, LteTft::UPLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 7895, 10, 0, 1)); + AddTestCase (new EpsTftClassifierTestCase (c4, LteTft::UPLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 9, 5897, 0, 2)); + AddTestCase (new EpsTftClassifierTestCase (c4, LteTft::DOWNLINK, Ipv4Address ("9.1.1.1"), Ipv4Address ("8.1.1.1"), 5897, 10, 0, 2)); + } diff --git a/src/lte/test/test-lte-epc-e2e-data.cc b/src/lte/test/test-lte-epc-e2e-data.cc index 4c4e73bf6..9bcfcf98a 100644 --- a/src/lte/test/test-lte-epc-e2e-data.cc +++ b/src/lte/test/test-lte-epc-e2e-data.cc @@ -50,13 +50,12 @@ NS_LOG_COMPONENT_DEFINE ("LteEpcE2eData"); -struct UeTestData +struct BearerTestData { - UeTestData (uint32_t n, uint32_t s); + BearerTestData (uint32_t n, uint32_t s); uint32_t numPkts; uint32_t pktSize; - EpsBearer epsBearer; Ptr dlServerApp; Ptr dlClientApp; @@ -65,13 +64,17 @@ struct UeTestData Ptr ulClientApp; }; -UeTestData::UeTestData (uint32_t n, uint32_t s) +BearerTestData::BearerTestData (uint32_t n, uint32_t s) : numPkts (n), - pktSize (s), - epsBearer (EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT)) + pktSize (s) { } +struct UeTestData +{ + std::vector bearers; +}; + struct EnbTestData { std::vector ues; @@ -154,7 +157,7 @@ LteEpcE2eDataTestCase::DoRun () NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbs); NetDeviceContainer::Iterator enbLteDevIt = enbLteDevs.Begin (); - uint16_t ulPort = 5678; + uint16_t ulPort = 1000; for (std::vector::iterator enbit = m_enbTestData.begin (); enbit < m_enbTestData.end (); @@ -193,50 +196,74 @@ LteEpcE2eDataTestCase::DoRun () Ptr ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject ()); ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1); + uint16_t dlPort = 2000; + for (uint32_t b = 0; b < enbit->ues.at (u).bearers.size (); ++b) + { + BearerTestData& bearerTestData = enbit->ues.at (u).bearers.at (b); + + { // Downlink + ++dlPort; + PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort)); + ApplicationContainer apps = packetSinkHelper.Install (ue); + apps.Start (Seconds (0.01)); + bearerTestData.dlServerApp = apps.Get (0)->GetObject (); + + Time interPacketInterval = Seconds (0.01); + UdpClientHelper client (ueIpIface.GetAddress (0), dlPort); + client.SetAttribute ("MaxPackets", UintegerValue (bearerTestData.numPkts)); + client.SetAttribute ("Interval", TimeValue (interPacketInterval)); + client.SetAttribute ("PacketSize", UintegerValue (bearerTestData.pktSize)); + apps = client.Install (remoteHost); + apps.Start (Seconds (0.01)); + bearerTestData.dlClientApp = apps.Get (0); + } - { // Downlink - uint16_t dlPort = 1234; - PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort)); - ApplicationContainer apps = packetSinkHelper.Install (ue); - apps.Start (Seconds (0.01)); - enbit->ues[u].dlServerApp = apps.Get (0)->GetObject (); + { // Uplink + ++ulPort; + PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort)); + ApplicationContainer apps = packetSinkHelper.Install (remoteHost); + apps.Start (Seconds (0.5)); + bearerTestData.ulServerApp = apps.Get (0)->GetObject (); - Time interPacketInterval = Seconds (0.01); - UdpClientHelper client (ueIpIface.GetAddress (0), dlPort); - client.SetAttribute ("MaxPackets", UintegerValue (enbit->ues[u].numPkts)); - client.SetAttribute ("Interval", TimeValue (interPacketInterval)); - client.SetAttribute ("PacketSize", UintegerValue (enbit->ues[u].pktSize)); - apps = client.Install (remoteHost); - apps.Start (Seconds (0.01)); - enbit->ues[u].dlClientApp = apps.Get (0); - } + Time interPacketInterval = Seconds (0.01); + UdpClientHelper client (remoteHostAddr, ulPort); + client.SetAttribute ("MaxPackets", UintegerValue (bearerTestData.numPkts)); + client.SetAttribute ("Interval", TimeValue (interPacketInterval)); + client.SetAttribute ("PacketSize", UintegerValue (bearerTestData.pktSize)); + apps = client.Install (ue); + apps.Start (Seconds (0.5)); + bearerTestData.ulClientApp = apps.Get (0); + } - { // Uplink - ++ulPort; - PacketSinkHelper packetSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort)); - ApplicationContainer apps = packetSinkHelper.Install (remoteHost); - apps.Start (Seconds (0.5)); - enbit->ues[u].ulServerApp = apps.Get (0)->GetObject (); - - Time interPacketInterval = Seconds (0.01); - UdpClientHelper client (remoteHostAddr, ulPort); - client.SetAttribute ("MaxPackets", UintegerValue (enbit->ues[u].numPkts)); - client.SetAttribute ("Interval", TimeValue (interPacketInterval)); - client.SetAttribute ("PacketSize", UintegerValue (enbit->ues[u].pktSize)); - apps = client.Install (ue); - apps.Start (Seconds (0.5)); - enbit->ues[u].ulClientApp = apps.Get (0); - } - - lteHelper->ActivateEpsBearer (ueLteDevice, enbit->ues[u].epsBearer, LteTft::Default ()); - + EpsBearer epsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT); + + Ptr tft = Create (); + LteTft::PacketFilter dlpf; + dlpf.localPortStart = dlPort; + dlpf.localPortEnd = dlPort; + tft->Add (dlpf); + LteTft::PacketFilter ulpf; + ulpf.remotePortStart = ulPort; + ulpf.remotePortEnd = ulPort; + tft->Add (ulpf); + + lteHelper->ActivateEpsBearer (ueLteDevice, epsBearer, tft); + } } } - Simulator::Stop (Seconds (2.0)); + lteHelper->EnableRlcTraces (); + lteHelper->EnablePdcpTraces (); + Time simulationTime = Seconds (2.0); + lteHelper->GetPdcpStats ()->SetAttribute ("EpochDuration", TimeValue (simulationTime)); + + + Simulator::Stop (simulationTime); Simulator::Run (); + static uint64_t imsiCounter = 0; + for (std::vector::iterator enbit = m_enbTestData.begin (); enbit < m_enbTestData.end (); ++enbit) @@ -244,9 +271,31 @@ LteEpcE2eDataTestCase::DoRun () for (std::vector::iterator ueit = enbit->ues.begin (); ueit < enbit->ues.end (); ++ueit) - { - NS_TEST_ASSERT_MSG_EQ (ueit->dlServerApp->GetTotalRx (), (ueit->numPkts) * (ueit->pktSize), "wrong total received bytes in downlink"); - NS_TEST_ASSERT_MSG_EQ (ueit->ulServerApp->GetTotalRx (), (ueit->numPkts) * (ueit->pktSize), "wrong total received bytes in uplink"); + { + uint64_t imsi = ++imsiCounter; + for (uint32_t b = 0; b < ueit->bearers.size (); ++b) + { + uint8_t lcid = b+1; + NS_TEST_ASSERT_MSG_EQ (lteHelper->GetPdcpStats ()->GetDlTxPackets (imsi, lcid), + ueit->bearers.at (b).numPkts, + "wrong TX PDCP packets in downlink for IMSI=" << imsi << " LCID=" << (uint16_t) lcid); + NS_TEST_ASSERT_MSG_EQ (lteHelper->GetPdcpStats ()->GetDlRxPackets (imsi, lcid), + ueit->bearers.at (b).numPkts, + "wrong RX PDCP packets in downlink for IMSI=" << imsi << " LCID=" << (uint16_t) lcid); + NS_TEST_ASSERT_MSG_EQ (lteHelper->GetPdcpStats ()->GetUlTxPackets (imsi, lcid), + ueit->bearers.at (b).numPkts, + "wrong TX PDCP packets in uplink for IMSI=" << imsi << " LCID=" << (uint16_t) lcid); + NS_TEST_ASSERT_MSG_EQ (lteHelper->GetPdcpStats ()->GetUlRxPackets (imsi, lcid), + ueit->bearers.at (b).numPkts, + "wrong RX PDCP packets in uplink for IMSI=" << imsi << " LCID=" << (uint16_t) lcid); + + NS_TEST_ASSERT_MSG_EQ (ueit->bearers.at (b).dlServerApp->GetTotalRx (), + (ueit->bearers.at (b).numPkts) * (ueit->bearers.at (b).pktSize), + "wrong total received bytes in downlink"); + NS_TEST_ASSERT_MSG_EQ (ueit->bearers.at (b).ulServerApp->GetTotalRx (), + (ueit->bearers.at (b).numPkts) * (ueit->bearers.at (b).pktSize), + "wrong total received bytes in uplink"); + } } } @@ -272,56 +321,80 @@ LteEpcE2eDataTestSuite::LteEpcE2eDataTestSuite () { std::vector v1; EnbTestData e1; - UeTestData f1 (1, 100); - e1.ues.push_back (f1); + UeTestData u1; + BearerTestData f1 (1, 100); + u1.bearers.push_back (f1); + e1.ues.push_back (u1); v1.push_back (e1); AddTestCase (new LteEpcE2eDataTestCase ("1 eNB, 1UE", v1)); - std::vector v2; EnbTestData e2; - UeTestData f2_1 (1, 100); - e2.ues.push_back (f2_1); - UeTestData f2_2 (2, 200); - e2.ues.push_back (f2_2); + UeTestData u2_1; + BearerTestData f2_1 (1, 100); + u2_1.bearers.push_back (f2_1); + e2.ues.push_back (u2_1); + UeTestData u2_2; + BearerTestData f2_2 (2, 200); + u2_2.bearers.push_back (f2_2); + e2.ues.push_back (u2_2); v2.push_back (e2); AddTestCase (new LteEpcE2eDataTestCase ("1 eNB, 2UEs", v2)); - std::vector v3; v3.push_back (e1); v3.push_back (e2); AddTestCase (new LteEpcE2eDataTestCase ("2 eNBs", v3)); - - EnbTestData e3; - UeTestData f3_1 (3, 50); - e3.ues.push_back (f3_1); - UeTestData f3_2 (5, 1400); - e3.ues.push_back (f3_2); - UeTestData f3_3 (1, 1); - e3.ues.push_back (f3_2); + EnbTestData e4; + UeTestData u4_1; + BearerTestData f4_1 (3, 50); + u4_1.bearers.push_back (f4_1); + e4.ues.push_back (u4_1); + UeTestData u4_2; + BearerTestData f4_2 (5, 1400); + u4_2.bearers.push_back (f4_2); + e4.ues.push_back (u4_2); + UeTestData u4_3; + BearerTestData f4_3 (1, 12); + u4_3.bearers.push_back (f4_3); + e4.ues.push_back (u4_3); std::vector v4; - v4.push_back (e3); + v4.push_back (e4); v4.push_back (e1); v4.push_back (e2); AddTestCase (new LteEpcE2eDataTestCase ("3 eNBs", v4)); - EnbTestData e4; - UeTestData f4_1 (5, 1000); - e4.ues.push_back (f4_1); + EnbTestData e5; + UeTestData u5; + BearerTestData f5 (5, 1000); + u5.bearers.push_back (f5); + e5.ues.push_back (u5); std::vector v5; - v5.push_back (e4); + v5.push_back (e5); AddTestCase (new LteEpcE2eDataTestCase ("1 eNB, 1UE with 1000 byte packets", v5)); - EnbTestData e5; - UeTestData f5_1 (5, 1400); - e5.ues.push_back (f5_1); + EnbTestData e6; + UeTestData u6; + BearerTestData f6 (5, 1400); + u6.bearers.push_back (f6); + e6.ues.push_back (u6); std::vector v6; - v6.push_back (e5); + v6.push_back (e6); AddTestCase (new LteEpcE2eDataTestCase ("1 eNB, 1UE with 1400 byte packets", v6)); + EnbTestData e7; + UeTestData u7; + BearerTestData f7_1 (1, 1400); + u7.bearers.push_back (f7_1); + BearerTestData f7_2 (1, 100); + u7.bearers.push_back (f7_2); + e7.ues.push_back (u7); + std::vector v7; + v7.push_back (e7); + AddTestCase (new LteEpcE2eDataTestCase ("1 eNB, 1UE with 2 bearers", v7)); + } 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',