From b55086476cb8c0464dc4a4c44d126b11f3e787f8 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 26 Feb 2019 12:11:38 +0100 Subject: [PATCH 1/7] network: Added API to be able to tag only some bytes --- src/network/model/packet.cc | 13 ++++++++++++- src/network/model/packet.h | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/network/model/packet.cc b/src/network/model/packet.cc index 3d888340f..876bcf191 100644 --- a/src/network/model/packet.cc +++ b/src/network/model/packet.cc @@ -820,11 +820,22 @@ Packet::AddByteTag (const Tag &tag) const { NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ()); ByteTagList *list = const_cast (&m_byteTagList); - TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (), + TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (), 0, GetSize ()); tag.Serialize (buffer); } +void +Packet::AddByteTag (const Tag &tag, uint32_t start, uint32_t end) const +{ + NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ()); + NS_ABORT_MSG_IF (end < start, "Invalid byte range"); + ByteTagList *list = const_cast (&m_byteTagList); + TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (), + static_cast (start), + static_cast (end)); + tag.Serialize (buffer); +} ByteTagIterator Packet::GetByteTagIterator (void) const { diff --git a/src/network/model/packet.h b/src/network/model/packet.h index dc9083cd1..e5387eb5c 100644 --- a/src/network/model/packet.h +++ b/src/network/model/packet.h @@ -571,6 +571,27 @@ public: * packet). */ void AddByteTag (const Tag &tag) const; + + /** + * \brief Tag the indicated byte range of this packet with a new byte tag. + * + * As parameters for this method, we do not use indexes, but byte position. + * Moreover, as there is no 0-th position, the first position is 1. + * + * As example, if you want to tag the first 10 bytes, you have to call + * the method in this way: + * + * \code{.cpp} + Ptr p = ... ; + SomeTag tag; + p->AddByteTag (tag, 1, 10); + \endcode + * + * \param tag the new tag to add to this packet + * \param start the position of the first byte tagged by this tag + * \param end the position of the last byte tagged by this tag + */ + void AddByteTag (const Tag &tag, uint32_t start, uint32_t end) const; /** * \brief Returns an iterator over the set of byte tags included in this packet * From c3030960024963223c7b6f088fc80a1b9aac6467 Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Mon, 25 Feb 2019 16:48:15 +0100 Subject: [PATCH 2/7] lte rlc am: Do not use a PacketTag to store the arrival time --- src/lte/model/lte-rlc-am.cc | 107 ++++++++++++++++++++---------------- src/lte/model/lte-rlc-am.h | 36 +++++++++--- 2 files changed, 90 insertions(+), 53 deletions(-) diff --git a/src/lte/model/lte-rlc-am.cc b/src/lte/model/lte-rlc-am.cc index 54e0e8e75..2f0dca818 100644 --- a/src/lte/model/lte-rlc-am.cc +++ b/src/lte/model/lte-rlc-am.cc @@ -157,11 +157,6 @@ LteRlcAm::DoTransmitPdcpPdu (Ptr p) { NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ()); - /** Store arrival time */ - Time now = Simulator::Now (); - RlcTag timeTag (now); - p->AddPacketTag (timeTag); - /** Store PDCP PDU */ LteRlcSduStatusTag tag; @@ -169,7 +164,7 @@ LteRlcAm::DoTransmitPdcpPdu (Ptr p) p->AddPacketTag (tag); NS_LOG_LOGIC ("Txon Buffer: New packet added"); - m_txonBuffer.push_back (p); + m_txonBuffer.push_back (TxPdu (p, Simulator::Now ())); m_txonBufferSize += p->GetSize (); NS_LOG_LOGIC ("NumOfBuffers = " << m_txonBuffer.size() ); NS_LOG_LOGIC ("txonBufferSize = " << m_txonBufferSize); @@ -258,8 +253,7 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara // Sender timestamp RlcTag rlcTag (Simulator::Now ()); - NS_ASSERT_MSG (!packet->PeekPacketTag (rlcTag), "RlcTag is already present"); - packet->AddPacketTag (rlcTag); + packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ()); m_txPdu (m_rnti, m_lcid, packet->GetSize ()); // Send RLC PDU to MAC layer @@ -292,8 +286,7 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara NS_LOG_LOGIC ("SN = " << seqNumberValue << " m_pdu " << m_retxBuffer.at (seqNumberValue).m_pdu); if (m_retxBuffer.at (seqNumberValue).m_pdu != 0) - { - + { Ptr packet = m_retxBuffer.at (seqNumberValue).m_pdu->Copy (); if (( packet->GetSize () <= txOpParams.bytes ) @@ -340,12 +333,14 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara } packet->AddHeader (rlcAmHeader); + + RlcTag rlcTag; + rlcTag.SetSenderTimestamp (Simulator::Now ()); + + packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ()); + NS_LOG_LOGIC ("new AM RLC header: " << rlcAmHeader); - // Sender timestamp - RlcTag rlcTag (Simulator::Now ()); - NS_ASSERT_MSG (packet->PeekPacketTag (rlcTag), "RlcTag is missing"); - packet->ReplacePacketTag (rlcTag); m_txPdu (m_rnti, m_lcid, packet->GetSize ()); // Send RLC PDU to MAC layer @@ -360,6 +355,7 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara m_macSapProvider->TransmitPdu (params); m_retxBuffer.at (seqNumberValue).m_retxCount++; + m_retxBuffer.at (seqNumberValue).m_waitingSince = Simulator::Now (); NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue); if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold) { @@ -369,11 +365,13 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara NS_LOG_INFO ("Move SN = " << seqNumberValue << " back to txedBuffer"); m_txedBuffer.at (seqNumberValue).m_pdu = m_retxBuffer.at (seqNumberValue).m_pdu->Copy (); m_txedBuffer.at (seqNumberValue).m_retxCount = m_retxBuffer.at (seqNumberValue).m_retxCount; + m_txedBuffer.at (seqNumberValue).m_waitingSince = m_retxBuffer.at (seqNumberValue).m_waitingSince; m_txedBufferSize += m_txedBuffer.at (seqNumberValue).m_pdu->GetSize (); m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize (); m_retxBuffer.at (seqNumberValue).m_pdu = 0; m_retxBuffer.at (seqNumberValue).m_retxCount = 0; + m_retxBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0); NS_LOG_LOGIC ("retxBufferSize = " << m_retxBufferSize); @@ -441,12 +439,13 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara } NS_LOG_LOGIC ("SDUs in TxonBuffer = " << m_txonBuffer.size ()); - NS_LOG_LOGIC ("First SDU buffer = " << *(m_txonBuffer.begin())); - NS_LOG_LOGIC ("First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ()); + NS_LOG_LOGIC ("First SDU buffer = " << m_txonBuffer.begin ()->m_pdu); + NS_LOG_LOGIC ("First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ()); NS_LOG_LOGIC ("Next segment size = " << nextSegmentSize); NS_LOG_LOGIC ("Remove SDU from TxBuffer"); - Ptr firstSegment = (*(m_txonBuffer.begin ()))->Copy (); - m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize (); + Time firstSegmentTime = m_txonBuffer.begin ()->m_waitingSince; + Ptr firstSegment = m_txonBuffer.begin ()->m_pdu->Copy (); + m_txonBufferSize -= m_txonBuffer.begin ()->m_pdu->GetSize (); NS_LOG_LOGIC ("txBufferSize = " << m_txonBufferSize ); m_txonBuffer.erase (m_txonBuffer.begin ()); @@ -496,12 +495,12 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara { firstSegment->AddPacketTag (oldTag); - m_txonBuffer.insert (m_txonBuffer.begin (), firstSegment); - m_txonBufferSize += (*(m_txonBuffer.begin()))->GetSize (); + m_txonBuffer.insert (m_txonBuffer.begin (), TxPdu (firstSegment, firstSegmentTime)); + m_txonBufferSize += m_txonBuffer.begin ()->m_pdu->GetSize (); NS_LOG_LOGIC (" Txon buffer: Give back the remaining segment"); NS_LOG_LOGIC (" Txon buffers = " << m_txonBuffer.size ()); - NS_LOG_LOGIC (" Front buffer size = " << (*(m_txonBuffer.begin()))->GetSize ()); + NS_LOG_LOGIC (" Front buffer size = " << m_txonBuffer.begin ()->m_pdu->GetSize ()); NS_LOG_LOGIC (" txonBufferSize = " << m_txonBufferSize ); } else @@ -563,8 +562,8 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ()); if (m_txonBuffer.size () > 0) { - NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin())); - NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ()); + NS_LOG_LOGIC (" First SDU buffer = " << m_txonBuffer.begin ()->m_pdu); + NS_LOG_LOGIC (" First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ()); } NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize); @@ -593,15 +592,16 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ()); if (m_txonBuffer.size () > 0) { - NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin())); - NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ()); + NS_LOG_LOGIC (" First SDU buffer = " << m_txonBuffer.begin ()->m_pdu); + NS_LOG_LOGIC (" First SDU size = " << m_txonBuffer.begin ()->m_pdu->GetSize ()); } NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize); NS_LOG_LOGIC (" Remove SDU from TxBuffer"); // (more segments) - firstSegment = (*(m_txonBuffer.begin ()))->Copy (); - m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize (); + firstSegment = m_txonBuffer.begin ()->m_pdu->Copy (); + firstSegmentTime = m_txonBuffer.begin ()->m_waitingSince; + m_txonBufferSize -= m_txonBuffer.begin ()->m_pdu->GetSize (); m_txonBuffer.erase (m_txonBuffer.begin ()); NS_LOG_LOGIC (" txBufferSize = " << m_txonBufferSize ); } @@ -716,17 +716,20 @@ LteRlcAm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara // Build RLC PDU with DataField and Header NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader); + + RlcTag rlcTag; + rlcTag.SetSenderTimestamp (Simulator::Now ()); + packet->AddHeader (rlcAmHeader); + packet->AddByteTag (rlcTag, 1, rlcAmHeader.GetSerializedSize ()); // Store new PDU into the Transmitted PDU Buffer NS_LOG_LOGIC ("Put transmitted PDU in the txedBuffer"); m_txedBufferSize += packet->GetSize (); m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_pdu = packet->Copy (); m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_retxCount = 0; + m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_waitingSince = Simulator::Now (); - // Sender timestamp - RlcTag rlcTag (Simulator::Now ()); - packet->ReplacePacketTag (rlcTag); m_txPdu (m_rnti, m_lcid, packet->GetSize ()); // Send RLC PDU to MAC layer @@ -753,19 +756,22 @@ LteRlcAm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams) { NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << rxPduParams.p->GetSize ()); - // Receiver timestamp - RlcTag rlcTag; - Time delay; - NS_ASSERT_MSG (rxPduParams.p->PeekPacketTag (rlcTag), "RlcTag is missing"); - rxPduParams.p->RemovePacketTag (rlcTag); - delay = Simulator::Now() - rlcTag.GetSenderTimestamp (); - m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), delay.GetNanoSeconds ()); - // Get RLC header parameters LteRlcAmHeader rlcAmHeader; rxPduParams.p->PeekHeader (rlcAmHeader); NS_LOG_LOGIC ("RLC header: " << rlcAmHeader); + // Receiver timestamp + Time delay; + RlcTag rlcTag; + + bool ret = rxPduParams.p->FindFirstMatchingByteTag (rlcTag); + NS_ASSERT_MSG(ret, "RlcTag not found in RLC Header. The packet went into a real network?"); + + delay = Simulator::Now () - rlcTag.GetSenderTimestamp (); + + m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), delay.GetNanoSeconds ()); + if ( rlcAmHeader.IsDataPdu () ) { @@ -1050,11 +1056,13 @@ LteRlcAm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams) NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer"); m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue).m_pdu->Copy (); m_retxBuffer.at (seqNumberValue).m_retxCount = m_txedBuffer.at (seqNumberValue).m_retxCount; + m_retxBuffer.at (seqNumberValue).m_waitingSince = m_txedBuffer.at (seqNumberValue).m_waitingSince; m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize (); m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize (); m_txedBuffer.at (seqNumberValue).m_pdu = 0; m_txedBuffer.at (seqNumberValue).m_retxCount = 0; + m_txedBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0); } NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu != 0); @@ -1070,6 +1078,7 @@ LteRlcAm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams) // NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ()); m_txedBufferSize -= m_txedBuffer.at (seqNumberValue).m_pdu->GetSize (); m_txedBuffer.at (seqNumberValue).m_pdu = 0; + m_txedBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0); NS_ASSERT (m_retxBuffer.at (seqNumberValue).m_pdu == 0); } @@ -1079,6 +1088,7 @@ LteRlcAm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams) m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize (); m_retxBuffer.at (seqNumberValue).m_pdu = 0; m_retxBuffer.at (seqNumberValue).m_retxCount = 0; + m_retxBuffer.at (seqNumberValue).m_waitingSince = MilliSeconds (0); } } @@ -1140,7 +1150,12 @@ void LteRlcAm::ReassembleAndDeliver (Ptr packet) { LteRlcAmHeader rlcAmHeader; + RlcTag rlcTag; + bool ret = packet->FindFirstMatchingByteTag (rlcTag); + NS_ASSERT(ret); packet->RemoveHeader (rlcAmHeader); + ret = packet->FindFirstMatchingByteTag (rlcTag); + NS_ASSERT(!ret); uint8_t framingInfo = rlcAmHeader.GetFramingInfo (); SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber (); bool expectedSnLost; @@ -1572,25 +1587,23 @@ LteRlcAm::DoReportBufferStatus (void) Time txonQueueHolDelay (0); if ( m_txonBufferSize > 0 ) { - RlcTag txonQueueHolTimeTag; - m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag); - txonQueueHolDelay = now - txonQueueHolTimeTag.GetSenderTimestamp (); + txonQueueHolDelay = now - m_txonBuffer.front ().m_waitingSince; } // Retransmission Queue HOL time Time retxQueueHolDelay; - RlcTag retxQueueHolTimeTag; if ( m_retxBufferSize > 0 ) { + Time senderTimestamp; if (m_retxBuffer.at (m_vtA.GetValue ()).m_pdu != 0) { - m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->PeekPacketTag (retxQueueHolTimeTag); + senderTimestamp = m_retxBuffer.at (m_vtA.GetValue ()).m_waitingSince; } else { - m_txedBuffer.at (m_vtA.GetValue ()).m_pdu->PeekPacketTag (retxQueueHolTimeTag); - } - retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp (); + senderTimestamp = m_txedBuffer.at (m_vtA.GetValue ()).m_waitingSince; + } + retxQueueHolDelay = now - senderTimestamp; } else { @@ -1700,11 +1713,13 @@ LteRlcAm::ExpirePollRetransmitTimer (void) NS_LOG_INFO ("Move PDU " << sn << " from txedBuffer to retxBuffer"); m_retxBuffer.at (snValue).m_pdu = m_txedBuffer.at (snValue).m_pdu->Copy (); m_retxBuffer.at (snValue).m_retxCount = m_txedBuffer.at (snValue).m_retxCount; + m_retxBuffer.at (snValue).m_waitingSince = m_txedBuffer.at (snValue).m_waitingSince; m_retxBufferSize += m_retxBuffer.at (snValue).m_pdu->GetSize (); m_txedBufferSize -= m_txedBuffer.at (snValue).m_pdu->GetSize (); m_txedBuffer.at (snValue).m_pdu = 0; m_txedBuffer.at (snValue).m_retxCount = 0; + m_txedBuffer.at (snValue).m_waitingSince = MilliSeconds (0); } } } diff --git a/src/lte/model/lte-rlc-am.h b/src/lte/model/lte-rlc-am.h index 47d8db08e..260d1e97f 100644 --- a/src/lte/model/lte-rlc-am.h +++ b/src/lte/model/lte-rlc-am.h @@ -107,14 +107,36 @@ private: void DoReportBufferStatus (); private: - std::vector < Ptr > m_txonBuffer; ///< Transmission buffer + /** + * \brief Store an incoming (from layer above us) PDU, waiting to transmit it + */ + struct TxPdu + { + /** + * \brief TxPdu default constructor + * \param pdu the PDU + * \param time the arrival time + */ + TxPdu (const Ptr &pdu, const Time &time) : + m_pdu (pdu), + m_waitingSince (time) + { } - /// RetxPdu structure - struct RetxPdu - { - Ptr m_pdu; ///< PDU - uint16_t m_retxCount; ///< retransmit count - }; + TxPdu () = delete; + + Ptr m_pdu; ///< PDU + Time m_waitingSince; ///< Layer arrival time + }; + + std::vector < TxPdu > m_txonBuffer; ///< Transmission buffer + + /// RetxPdu structure + struct RetxPdu + { + Ptr m_pdu; ///< PDU + uint16_t m_retxCount; ///< retransmit count + Time m_waitingSince; ///!< Layer arrival time + }; std::vector m_txedBuffer; ///< Buffer for transmitted and retransmitted PDUs ///< that have not been acked but are not considered From 66f1e9198cc3bbc69bb5f24e517fe10b7fead142 Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Wed, 27 Feb 2019 09:55:23 +0100 Subject: [PATCH 3/7] lte rlc um: Do not use a PacketTag to store the arrival time --- src/lte/model/lte-rlc-um.cc | 49 +++++++++++++++++-------------------- src/lte/model/lte-rlc-um.h | 23 ++++++++++++++++- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/lte/model/lte-rlc-um.cc b/src/lte/model/lte-rlc-um.cc index 794571591..19a276f0e 100644 --- a/src/lte/model/lte-rlc-um.cc +++ b/src/lte/model/lte-rlc-um.cc @@ -88,18 +88,13 @@ LteRlcUm::DoTransmitPdcpPdu (Ptr p) if (m_txBufferSize + p->GetSize () <= m_maxTxBufferSize) { - /** Store arrival time */ - RlcTag timeTag (Simulator::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); + m_txBuffer.push_back (TxPdu (p, Simulator::Now ())); m_txBufferSize += p->GetSize (); NS_LOG_LOGIC ("NumOfBuffers = " << m_txBuffer.size() ); NS_LOG_LOGIC ("txBufferSize = " << m_txBufferSize); @@ -153,13 +148,15 @@ LteRlcUm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara return; } + Ptr firstSegment = m_txBuffer.begin ()->m_pdu->Copy (); + Time firstSegmentTime = m_txBuffer.begin ()->m_waitingSince; + NS_LOG_LOGIC ("SDUs in TxBuffer = " << m_txBuffer.size ()); - NS_LOG_LOGIC ("First SDU buffer = " << *(m_txBuffer.begin())); - NS_LOG_LOGIC ("First SDU size = " << (*(m_txBuffer.begin()))->GetSize ()); + NS_LOG_LOGIC ("First SDU buffer = " << firstSegment); + NS_LOG_LOGIC ("First SDU size = " << firstSegment->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_txBufferSize -= firstSegment->GetSize (); NS_LOG_LOGIC ("txBufferSize = " << m_txBufferSize ); m_txBuffer.erase (m_txBuffer.begin ()); @@ -209,12 +206,12 @@ LteRlcUm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara { firstSegment->AddPacketTag (oldTag); - m_txBuffer.insert (m_txBuffer.begin (), firstSegment); - m_txBufferSize += (*(m_txBuffer.begin()))->GetSize (); + m_txBuffer.insert (m_txBuffer.begin (), TxPdu (firstSegment, firstSegmentTime)); + m_txBufferSize += m_txBuffer.begin()->m_pdu->GetSize (); 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 (" Front buffer size = " << m_txBuffer.begin()->m_pdu->GetSize ()); NS_LOG_LOGIC (" txBufferSize = " << m_txBufferSize ); } else @@ -275,8 +272,8 @@ LteRlcUm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txBuffer.size ()); if (m_txBuffer.size () > 0) { - NS_LOG_LOGIC (" First SDU buffer = " << *(m_txBuffer.begin())); - NS_LOG_LOGIC (" First SDU size = " << (*(m_txBuffer.begin()))->GetSize ()); + NS_LOG_LOGIC (" First SDU buffer = " << m_txBuffer.begin()->m_pdu); + NS_LOG_LOGIC (" First SDU size = " << m_txBuffer.begin()->m_pdu->GetSize ()); } NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize); @@ -305,15 +302,16 @@ LteRlcUm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txBuffer.size ()); if (m_txBuffer.size () > 0) { - NS_LOG_LOGIC (" First SDU buffer = " << *(m_txBuffer.begin())); - NS_LOG_LOGIC (" First SDU size = " << (*(m_txBuffer.begin()))->GetSize ()); + NS_LOG_LOGIC (" First SDU buffer = " << m_txBuffer.begin()->m_pdu); + NS_LOG_LOGIC (" First SDU size = " << m_txBuffer.begin()->m_pdu->GetSize ()); } NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize); NS_LOG_LOGIC (" Remove SDU from TxBuffer"); // (more segments) - firstSegment = (*(m_txBuffer.begin ()))->Copy (); - m_txBufferSize -= (*(m_txBuffer.begin()))->GetSize (); + firstSegment = m_txBuffer.begin ()->m_pdu->Copy (); + firstSegmentTime = m_txBuffer.begin ()->m_waitingSince; + m_txBufferSize -= firstSegment->GetSize (); m_txBuffer.erase (m_txBuffer.begin ()); NS_LOG_LOGIC (" txBufferSize = " << m_txBufferSize ); } @@ -379,7 +377,7 @@ LteRlcUm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara // Sender timestamp RlcTag rlcTag (Simulator::Now ()); - packet->ReplacePacketTag (rlcTag); + packet->AddByteTag (rlcTag, 1, rlcHeader.GetSerializedSize ()); m_txPdu (m_rnti, m_lcid, packet->GetSize ()); // Send RLC PDU to MAC layer @@ -414,8 +412,10 @@ LteRlcUm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams) // Receiver timestamp RlcTag rlcTag; Time delay; - NS_ASSERT_MSG (rxPduParams.p->PeekPacketTag (rlcTag), "RlcTag is missing"); - rxPduParams.p->RemovePacketTag (rlcTag); + + bool ret = rxPduParams.p->FindFirstMatchingByteTag (rlcTag); + NS_ASSERT_MSG (ret, "RlcTag is missing"); + delay = Simulator::Now() - rlcTag.GetSenderTimestamp (); m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), delay.GetNanoSeconds ()); @@ -1123,10 +1123,7 @@ LteRlcUm::DoReportBufferStatus (void) if (! m_txBuffer.empty ()) { - RlcTag holTimeTag; - NS_ASSERT_MSG (m_txBuffer.front ()->PeekPacketTag (holTimeTag), "RlcTag is missing"); - m_txBuffer.front ()->PeekPacketTag (holTimeTag); - holDelay = Simulator::Now () - holTimeTag.GetSenderTimestamp (); + holDelay = Simulator::Now () - m_txBuffer.front().m_waitingSince; queueSize = m_txBufferSize + 2 * m_txBuffer.size (); // Data in tx queue + estimated headers size } diff --git a/src/lte/model/lte-rlc-um.h b/src/lte/model/lte-rlc-um.h index 5cbcbca42..97ac7136d 100644 --- a/src/lte/model/lte-rlc-um.h +++ b/src/lte/model/lte-rlc-um.h @@ -97,7 +97,28 @@ private: private: uint32_t m_maxTxBufferSize; ///< maximum transmit buffer status uint32_t m_txBufferSize; ///< transmit buffer size - std::vector < Ptr > m_txBuffer; ///< Transmission buffer + /** + * \brief Store an incoming (from layer above us) PDU, waiting to transmit it + */ + struct TxPdu + { + /** + * \brief TxPdu default constructor + * \param pdu the PDU + * \param time the arrival time + */ + TxPdu (const Ptr &pdu, const Time &time) : + m_pdu (pdu), + m_waitingSince (time) + { } + + TxPdu () = delete; + + Ptr m_pdu; ///< PDU + Time m_waitingSince; ///< Layer arrival time + }; + + std::vector < TxPdu > m_txBuffer; ///< Transmission buffer std::map > m_rxBuffer; ///< Reception buffer std::vector < Ptr > m_reasBuffer; ///< Reassembling buffer From f2d3ffed57b8ec764ccd870ed6782d50fd28cd13 Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Wed, 27 Feb 2019 10:33:41 +0100 Subject: [PATCH 4/7] lte rlc tm: Disable delay measurements --- src/lte/model/lte-rlc-tm.cc | 32 ++++++++------------------------ src/lte/model/lte-rlc-tm.h | 29 +++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/lte/model/lte-rlc-tm.cc b/src/lte/model/lte-rlc-tm.cc index 70f48d918..78d279ab2 100644 --- a/src/lte/model/lte-rlc-tm.cc +++ b/src/lte/model/lte-rlc-tm.cc @@ -23,7 +23,6 @@ #include "ns3/log.h" #include "ns3/lte-rlc-tm.h" -#include "ns3/lte-rlc-tag.h" namespace ns3 { @@ -81,12 +80,8 @@ LteRlcTm::DoTransmitPdcpPdu (Ptr p) if (m_txBufferSize + p->GetSize () <= m_maxTxBufferSize) { - /** Store arrival time */ - RlcTag timeTag (Simulator::Now ()); - p->AddPacketTag (timeTag); - NS_LOG_LOGIC ("Tx Buffer: New packet added"); - m_txBuffer.push_back (p); + m_txBuffer.push_back (TxPdu (p, Simulator::Now ())); m_txBufferSize += p->GetSize (); NS_LOG_LOGIC ("NumOfBuffers = " << m_txBuffer.size() ); NS_LOG_LOGIC ("txBufferSize = " << m_txBufferSize); @@ -127,20 +122,18 @@ LteRlcTm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara return; } - Ptr packet = (*(m_txBuffer.begin ()))->Copy (); + Ptr packet = m_txBuffer.begin ()->m_pdu->Copy (); if (txOpParams.bytes < packet->GetSize ()) { - NS_LOG_WARN ("TX opportunity too small = " << txOpParams.bytes << " (PDU size: " << packet->GetSize () << ")"); + NS_LOG_WARN ("TX opportunity too small = " << txOpParams.bytes << + " (PDU size: " << packet->GetSize () << ")"); return; } - m_txBufferSize -= (*(m_txBuffer.begin()))->GetSize (); + m_txBufferSize -= packet->GetSize (); m_txBuffer.erase (m_txBuffer.begin ()); - - // Sender timestamp - RlcTag rlcTag (Simulator::Now ()); - packet->ReplacePacketTag (rlcTag); + m_txPdu (m_rnti, m_lcid, packet->GetSize ()); // Send RLC PDU to MAC layer @@ -172,13 +165,7 @@ LteRlcTm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams) { NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << rxPduParams.p->GetSize ()); - // Receiver timestamp - RlcTag rlcTag; - Time delay; - NS_ASSERT_MSG (rxPduParams.p->PeekPacketTag (rlcTag), "RlcTag is missing"); - rxPduParams.p->RemovePacketTag (rlcTag); - delay = Simulator::Now() - rlcTag.GetSenderTimestamp (); - m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), delay.GetNanoSeconds ()); + m_rxPdu (m_rnti, m_lcid, rxPduParams.p->GetSize (), 0); // 5.1.1.2 Receive operations // 5.1.1.2.1 General @@ -197,10 +184,7 @@ LteRlcTm::DoReportBufferStatus (void) if (! m_txBuffer.empty ()) { - RlcTag holTimeTag; - NS_ASSERT_MSG (m_txBuffer.front ()->PeekPacketTag (holTimeTag), "RlcTag is missing"); - m_txBuffer.front ()->PeekPacketTag (holTimeTag); - holDelay = Simulator::Now () - holTimeTag.GetSenderTimestamp (); + holDelay = Simulator::Now () - m_txBuffer.front ().m_waitingSince; queueSize = m_txBufferSize; // just data in tx queue (no header overhead for RLC TM) } diff --git a/src/lte/model/lte-rlc-tm.h b/src/lte/model/lte-rlc-tm.h index 8b030d32a..ea7f68c2b 100644 --- a/src/lte/model/lte-rlc-tm.h +++ b/src/lte/model/lte-rlc-tm.h @@ -31,6 +31,10 @@ namespace ns3 { /** * LTE RLC Transparent Mode (TM), see 3GPP TS 36.322 + * + * Please note that, as in TM it is not possible to add any header, the delay + * measurements gathered from the trace source "RxPDU" of LteRlc are invalid + * (they will be always 0) */ class LteRlcTm : public LteRlc { @@ -70,12 +74,33 @@ private: void DoReportBufferStatus (); private: + /** + * \brief Store an incoming (from layer above us) PDU, waiting to transmit it + */ + struct TxPdu + { + /** + * \brief TxPdu default constructor + * \param pdu the PDU + * \param time the arrival time + */ + TxPdu (const Ptr &pdu, const Time &time) : + m_pdu (pdu), + m_waitingSince (time) + { } + + TxPdu () = delete; + + Ptr m_pdu; ///< PDU + Time m_waitingSince; ///< Layer arrival time + }; + + std::vector < TxPdu > m_txBuffer; ///< Transmission buffer + uint32_t m_maxTxBufferSize; ///< maximum transmit buffer size uint32_t m_txBufferSize; ///< transmit buffer size - std::vector < Ptr > m_txBuffer; ///< Transmission buffer EventId m_rbsTimer; ///< RBS timer - }; From 4394583f3a016068f330caf9727b4396567be184 Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Wed, 27 Feb 2019 10:33:56 +0100 Subject: [PATCH 5/7] lte pdcp: Do not use a PacketTag to store the arrival time --- src/lte/model/lte-pdcp.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lte/model/lte-pdcp.cc b/src/lte/model/lte-pdcp.cc index 3f7acd32f..07b652bd7 100644 --- a/src/lte/model/lte-pdcp.cc +++ b/src/lte/model/lte-pdcp.cc @@ -178,6 +178,9 @@ LtePdcp::DoTransmitPdcpSdu (Ptr p) { NS_LOG_FUNCTION (this << m_rnti << (uint32_t) m_lcid << p->GetSize ()); + // Sender timestamp + PdcpTag pdcpTag (Simulator::Now ()); + LtePdcpHeader pdcpHeader; pdcpHeader.SetSequenceNumber (m_txSequenceNumber); @@ -191,10 +194,8 @@ LtePdcp::DoTransmitPdcpSdu (Ptr p) NS_LOG_LOGIC ("PDCP header: " << pdcpHeader); p->AddHeader (pdcpHeader); + p->AddByteTag (pdcpTag, 1, pdcpHeader.GetSerializedSize ()); - // Sender timestamp - PdcpTag pdcpTag (Simulator::Now ()); - p->AddPacketTag (pdcpTag); m_txPdu (m_rnti, m_lcid, p->GetSize ()); LteRlcSapProvider::TransmitPdcpPduParameters params; @@ -213,8 +214,7 @@ LtePdcp::DoReceivePdu (Ptr p) // Receiver timestamp PdcpTag pdcpTag; Time delay; - NS_ASSERT_MSG (p->PeekPacketTag (pdcpTag), "PdcpTag is missing"); - p->RemovePacketTag (pdcpTag); + p->FindFirstMatchingByteTag (pdcpTag); delay = Simulator::Now() - pdcpTag.GetSenderTimestamp (); m_rxPdu(m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds ()); From f20674cead922ba4c5b105a8384f9a0986c4fa38 Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Thu, 28 Feb 2019 10:20:42 +0100 Subject: [PATCH 6/7] lte: Updating CHANGES.html to reflect trace changes in RLC TM mode --- CHANGES.html | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.html b/CHANGES.html index 31635047b..877858e17 100644 --- a/CHANGES.html +++ b/CHANGES.html @@ -116,6 +116,7 @@ us a note on ns-developers mailing list.

  • The default qdisc installed on single-queue devices (such as PointToPoint, Csma and Simple) is now FqCodel (instead of PfifoFast). On multi-queue devices (such as Wifi), the default root qdisc is now Mq with as many FqCoDel child qdiscs as the number of device queues. The new defaults are motivated by the willingness to align with the behavior of major Linux distributions and by the need to preserve the effectiveness of Wifi EDCA Functions in differentiating Access Categories (see issue #35).
  • +
  • LTE RLC TM mode does not report anymore the layer-to-layer delay, as it misses (by standard) an header to which attach the timestamp tag. Users can switch to the PDCP layer delay measurements, which must be the same.

  • From a5fa8efd130529fe5ea9b1ed82890d7379735258 Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Wed, 20 Mar 2019 18:41:46 +0100 Subject: [PATCH 7/7] lte: Added a fake header to RLC SM to be able to measure the layer-to-layer delay --- src/lte/model/lte-rlc.cc | 88 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/src/lte/model/lte-rlc.cc b/src/lte/model/lte-rlc.cc index f8bde0e83..23ec63c21 100644 --- a/src/lte/model/lte-rlc.cc +++ b/src/lte/model/lte-rlc.cc @@ -32,6 +32,80 @@ namespace ns3 { NS_LOG_COMPONENT_DEFINE ("LteRlc"); +/** + * Tag to calculate the per-PDU delay from eNb RLC to UE RLC + */ + +class RlcSmHeader : public Header +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + + /** + * Create an empty RLC tag + */ + RlcSmHeader (); + + virtual void Serialize (Buffer::Iterator i) const; + virtual uint32_t Deserialize (Buffer::Iterator i); + virtual uint32_t GetSerializedSize () const; + virtual void Print (std::ostream &os) const; +}; + +RlcSmHeader::RlcSmHeader () : Header () +{ + // Nothing to do here +} + + +TypeId +RlcSmHeader::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::RlcSmTag") + .SetParent
    () + .SetGroupName("Lte") + .AddConstructor (); + return tid; +} + +TypeId +RlcSmHeader::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +uint32_t +RlcSmHeader::GetSerializedSize (void) const +{ + return 1; +} + +void +RlcSmHeader::Serialize (Buffer::Iterator i) const +{ + // Arbitrary value. It is not used anywhere. + i.WriteU8 (8U); +} + +uint32_t +RlcSmHeader::Deserialize (Buffer::Iterator i) +{ + uint8_t v = i.ReadU8 (); + NS_UNUSED (v); + return 1; +} + +void +RlcSmHeader::Print (std::ostream &os) const +{ + os << "RlcSmTag"; +} + /// LteRlcSpecificLteMacSapUser class class LteRlcSpecificLteMacSapUser : public LteMacSapUser @@ -223,8 +297,8 @@ LteRlcSm::DoReceivePdu (LteMacSapUser::ReceivePduParameters rxPduParams) // RLC Performance evaluation RlcTag rlcTag; Time delay; - NS_ASSERT_MSG (rxPduParams.p->PeekPacketTag (rlcTag), "RlcTag is missing"); - rxPduParams.p->RemovePacketTag (rlcTag); + bool ret = rxPduParams.p->FindFirstMatchingByteTag (rlcTag); + NS_ASSERT_MSG (ret, "RlcTag is missing"); delay = Simulator::Now() - rlcTag.GetSenderTimestamp (); NS_LOG_LOGIC (" RNTI=" << m_rnti << " LCID=" << (uint32_t) m_lcid @@ -238,7 +312,13 @@ LteRlcSm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara { NS_LOG_FUNCTION (this << txOpParams.bytes); LteMacSapProvider::TransmitPduParameters params; - params.pdu = Create (txOpParams.bytes); + RlcSmHeader header; + RlcTag tag (Simulator::Now ()); + + params.pdu = Create (txOpParams.bytes - header.GetSerializedSize ()); + params.pdu->AddHeader (header); + params.pdu->AddByteTag (tag, 1, header.GetSerializedSize ()); + params.rnti = m_rnti; params.lcid = m_lcid; params.layer = txOpParams.layer; @@ -246,8 +326,6 @@ LteRlcSm::DoNotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpPara params.componentCarrierId = txOpParams.componentCarrierId; // RLC Performance evaluation - RlcTag tag (Simulator::Now()); - params.pdu->AddPacketTag (tag); NS_LOG_LOGIC (" RNTI=" << m_rnti << " LCID=" << (uint32_t) m_lcid << " size=" << txOpParams.bytes);