diff --git a/src/lte/model/lte-rlc-um.cc b/src/lte/model/lte-rlc-um.cc index 5b10bff11..233fc8b6b 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,6 +71,11 @@ 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; @@ -76,19 +83,28 @@ LteRlcUm::DoTransmitPdcpPdu (Ptr p) p->AddPacketTag (tag); 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 ("Tx Buffer: New packet added"); + NS_LOG_LOGIC ("NumOfBuffers = " << m_txBuffer.size() ); /** 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; + 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 +145,11 @@ 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 (); m_txBuffer.erase (m_txBuffer.begin ()); while ( firstSegment && (firstSegment->GetSize () > 0) && (nextSegmentSize > 0) ) @@ -172,6 +186,7 @@ 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"); 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/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 */