Merge branch 'header-tag-dev' into 'master'

Extend core API to tag byte ranges -- first use case: Avoid the use of PacketTag in LTE PDCP and RLC, ByteTagging only their headers

See merge request nsnam/ns-3-dev!32
This commit is contained in:
N
2019-04-25 13:50:08 +00:00
11 changed files with 292 additions and 117 deletions

View File

@@ -116,6 +116,7 @@ us a note on ns-developers mailing list.</p>
</ul>
</li>
<li> 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).</li>
<li>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.</li>
</ul>
<hr>

View File

@@ -178,6 +178,9 @@ LtePdcp::DoTransmitPdcpSdu (Ptr<Packet> 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<Packet> 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<Packet> 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 ());

View File

@@ -157,11 +157,6 @@ LteRlcAm::DoTransmitPdcpPdu (Ptr<Packet> 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<Packet> 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> 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<Packet> firstSegment = (*(m_txonBuffer.begin ()))->Copy ();
m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
Time firstSegmentTime = m_txonBuffer.begin ()->m_waitingSince;
Ptr<Packet> 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> 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);
}
}
}

View File

@@ -107,14 +107,36 @@ private:
void DoReportBufferStatus ();
private:
std::vector < Ptr<Packet> > 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<Packet> &pdu, const Time &time) :
m_pdu (pdu),
m_waitingSince (time)
{ }
/// RetxPdu structure
struct RetxPdu
{
Ptr<Packet> m_pdu; ///< PDU
uint16_t m_retxCount; ///< retransmit count
};
TxPdu () = delete;
Ptr<Packet> m_pdu; ///< PDU
Time m_waitingSince; ///< Layer arrival time
};
std::vector < TxPdu > m_txonBuffer; ///< Transmission buffer
/// RetxPdu structure
struct RetxPdu
{
Ptr<Packet> m_pdu; ///< PDU
uint16_t m_retxCount; ///< retransmit count
Time m_waitingSince; ///!< Layer arrival time
};
std::vector <RetxPdu> m_txedBuffer; ///< Buffer for transmitted and retransmitted PDUs
///< that have not been acked but are not considered

View File

@@ -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<Packet> 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> packet = (*(m_txBuffer.begin ()))->Copy ();
Ptr<Packet> 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)
}

View File

@@ -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<Packet> &pdu, const Time &time) :
m_pdu (pdu),
m_waitingSince (time)
{ }
TxPdu () = delete;
Ptr<Packet> 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<Packet> > m_txBuffer; ///< Transmission buffer
EventId m_rbsTimer; ///< RBS timer
};

View File

@@ -88,18 +88,13 @@ LteRlcUm::DoTransmitPdcpPdu (Ptr<Packet> 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<Packet> 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<Packet> 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
}

View File

@@ -97,7 +97,28 @@ private:
private:
uint32_t m_maxTxBufferSize; ///< maximum transmit buffer status
uint32_t m_txBufferSize; ///< transmit buffer size
std::vector < Ptr<Packet> > 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<Packet> &pdu, const Time &time) :
m_pdu (pdu),
m_waitingSince (time)
{ }
TxPdu () = delete;
Ptr<Packet> m_pdu; ///< PDU
Time m_waitingSince; ///< Layer arrival time
};
std::vector < TxPdu > m_txBuffer; ///< Transmission buffer
std::map <uint16_t, Ptr<Packet> > m_rxBuffer; ///< Reception buffer
std::vector < Ptr<Packet> > m_reasBuffer; ///< Reassembling buffer

View File

@@ -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<Header> ()
.SetGroupName("Lte")
.AddConstructor<RlcSmHeader> ();
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<Packet> (txOpParams.bytes);
RlcSmHeader header;
RlcTag tag (Simulator::Now ());
params.pdu = Create<Packet> (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);

View File

@@ -820,11 +820,22 @@ Packet::AddByteTag (const Tag &tag) const
{
NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
ByteTagList *list = const_cast<ByteTagList *> (&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<ByteTagList *> (&m_byteTagList);
TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
static_cast<int32_t> (start),
static_cast<int32_t> (end));
tag.Serialize (buffer);
}
ByteTagIterator
Packet::GetByteTagIterator (void) const
{

View File

@@ -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<Packet> 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
*