--- a/src/lte/model/lte-rlc-am-header.cc Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/model/lte-rlc-am-header.cc Wed Feb 08 17:14:58 2012 +0100
@@ -89,9 +89,9 @@
}
void
-LteRlcAmHeader::SetSequenceNumber (uint16_t sequenceNumber)
+LteRlcAmHeader::SetSequenceNumber (SequenceNumber10 sequenceNumber)
{
- m_sequenceNumber = sequenceNumber & 0x03FF;
+ m_sequenceNumber = sequenceNumber;
}
uint8_t
@@ -100,7 +100,7 @@
return m_framingInfo;
}
-uint16_t
+SequenceNumber10
LteRlcAmHeader::GetSequenceNumber () const
{
return m_sequenceNumber;
@@ -209,12 +209,12 @@
void
-LteRlcAmHeader::SetAckSn (uint16_t ackSn)
+LteRlcAmHeader::SetAckSn (SequenceNumber10 ackSn)
{
- m_ackSn = ackSn & 0x03FF;
+ m_ackSn = ackSn;
}
-uint16_t
+SequenceNumber10
LteRlcAmHeader::GetAckSn (void) const
{
return m_ackSn;
@@ -303,8 +303,8 @@
((m_pollingBit << 5) & 0x20) |
((m_framingInfo << 3) & 0x18) |
(((*it1) << 2) & 0x04) |
- ((m_sequenceNumber >> 8) & 0x0003) );
- i.WriteU8 ( m_sequenceNumber & 0x00FF );
+ ((m_sequenceNumber.GetValue () >> 8) & 0x0003) );
+ i.WriteU8 ( m_sequenceNumber.GetValue () & 0x00FF );
i.WriteU8 ( ((m_lastSegmentFlag << 7) & 0x80) |
((m_segmentOffset >> 8) & 0x007F) );
i.WriteU8 ( m_segmentOffset & 0x00FF );
@@ -346,8 +346,8 @@
{
i.WriteU8 ( ((CONTROL_PDU << 7) & 0x80) |
((m_controlPduType << 4) & 0x70) |
- ((m_ackSn >> 6) & 0x0F) );
- i.WriteU8 ( ((m_ackSn << 2) & 0xC0) );
+ ((m_ackSn.GetValue () >> 6) & 0x0F) );
+ i.WriteU8 ( ((m_ackSn.GetValue () << 2) & 0xFC) );
}
}
@@ -378,7 +378,7 @@
m_lastSegmentFlag = (byte_3 & 0x80) >> 7;
m_segmentOffset = (byte_3 & 0x7F) | byte_4;
-
+
extensionBit = (byte_1 & 0x04) >> 2;
m_extensionBits.push_back (extensionBit);
--- a/src/lte/model/lte-rlc-am-header.h Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/model/lte-rlc-am-header.h Wed Feb 08 17:14:58 2012 +0100
@@ -22,6 +22,7 @@
#define LTE_RLC_AM_HEADER_H
#include "ns3/header.h"
+#include "ns3/lte-rlc-sequence-number.h"
#include <list>
@@ -65,8 +66,8 @@
// DATA PDU
//
- void SetSequenceNumber (uint16_t sequenceNumber);
- uint16_t GetSequenceNumber () const;
+ void SetSequenceNumber (SequenceNumber10 sequenceNumber);
+ SequenceNumber10 GetSequenceNumber () const;
void SetFramingInfo (uint8_t framingInfo);
uint8_t GetFramingInfo () const;
@@ -124,8 +125,8 @@
// CONTROL PDU
//
- void SetAckSn (uint16_t ackSn);
- uint16_t GetAckSn () const;
+ void SetAckSn (SequenceNumber10 ackSn);
+ SequenceNumber10 GetAckSn () const;
static TypeId GetTypeId (void);
@@ -143,7 +144,7 @@
uint8_t m_resegmentationFlag;
uint8_t m_pollingBit;
uint8_t m_framingInfo; // 2 bits
- uint16_t m_sequenceNumber; // 10 bits
+ SequenceNumber10 m_sequenceNumber;
uint8_t m_lastSegmentFlag;
uint16_t m_segmentOffset;
uint16_t m_lastOffset;
@@ -155,8 +156,8 @@
uint8_t m_controlPduType;
// Status PDU fields
- uint16_t m_ackSn;
- uint16_t m_nackSn;
+ SequenceNumber10 m_ackSn;
+ SequenceNumber10 m_nackSn;
std::list <uint8_t> m_extensionBits1; // Includes E1 after ACK_SN
std::list <uint8_t> m_extensionBits2;
--- a/src/lte/model/lte-rlc-am.cc Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/model/lte-rlc-am.cc Wed Feb 08 17:14:58 2012 +0100
@@ -38,9 +38,9 @@
// Buffers
m_txonBufferSize = 0;
- m_retxBuffer.resize (512);
+ m_retxBuffer.resize (1024);
m_retxBufferSize = 0;
- m_txedBuffer.resize (512);
+ m_txedBuffer.resize (1024);
m_txedBufferSize = 0;
m_statusPduRequested = false;
@@ -129,7 +129,7 @@
Time retxQueueHolDelay (0);
if ( m_retxBufferSize )
{
- m_retxBuffer.front ().m_pdu->PeekPacketTag (retxQueueHolTimeTag);
+//MRE m_retxBuffer.front ().m_pdu->PeekPacketTag (retxQueueHolTimeTag);
retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
}
@@ -186,10 +186,25 @@
params.lcid = m_lcid;
m_macSapProvider->TransmitPdu (params);
+ return;
}
else if ( m_retxBufferSize > 0 )
{
NS_LOG_LOGIC ("Sending data from Retransmission Buffer");
+
+ Ptr<Packet> packet = m_retxBuffer.at (m_vtA.GetValue ()).m_pdu;
+
+ if ( packet->GetSize () <= bytes )
+ {
+ // Send RLC PDU to MAC layer
+ LteMacSapProvider::TransmitPduParameters params;
+ params.pdu = packet;
+ params.rnti = m_rnti;
+ params.lcid = m_lcid;
+
+ m_macSapProvider->TransmitPdu (params);
+ return;
+ }
}
else if ( m_txonBufferSize > 0 )
{
@@ -212,7 +227,7 @@
rlcAmHeader.SetDataPdu ();
// Build Data field
- uint32_t nextSegmentSize = bytes - 2;
+ uint32_t nextSegmentSize = bytes - 4;
uint32_t nextSegmentId = 1;
uint32_t dataFieldTotalSize = 0;
uint32_t dataFieldAddedSize = 0;
@@ -304,7 +319,7 @@
dataFieldAddedSize = firstSegment->GetSize ();
dataFieldTotalSize += dataFieldAddedSize;
dataField.push_back (firstSegment);
- firstSegment = 0; // TODO how to put a null ptr to Packet?
+ firstSegment = 0;
// ExtensionBit (Next_Segment - 1) = 0
rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
@@ -320,9 +335,9 @@
NS_LOG_LOGIC (" First SDU buffer = " << *(m_txonBuffer.begin()));
NS_LOG_LOGIC (" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
}
- NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize << " (should be 0)");
+ NS_LOG_LOGIC (" Next segment size = " << nextSegmentSize);
- // nextSegmentSize MUST be zero
+ // nextSegmentSize MUST be zero (only if txonBuffer is not empty)
// (NO more segments) → exit
// break;
@@ -341,7 +356,7 @@
// LengthIndicator (Next_Segment) = txBuffer.FirstBuffer.length()
rlcAmHeader.PushLengthIndicator (firstSegment->GetSize ());
- nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize; // TODO???
+ nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
nextSegmentId++;
NS_LOG_LOGIC (" SDUs in TxBuffer = " << m_txonBuffer.size ());
@@ -366,9 +381,7 @@
// Build RLC header
//
- rlcAmHeader.SetSequenceNumber ( m_vtS );
- m_vtS = (m_vtS + 1) % 1024;
-
+ rlcAmHeader.SetSequenceNumber ( m_vtS++ );
rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
rlcAmHeader.SetSegmentOffset (0);
@@ -444,7 +457,7 @@
{
NS_LOG_LOGIC ("Start PollRetransmit timer");
- m_pollRetransmitTimer = Simulator::Schedule (Time ("1.0s"),
+ m_pollRetransmitTimer = Simulator::Schedule (Time ("0.1s"),
&LteRlcAm::ExpirePollRetransmitTimer, this);
}
else
@@ -452,7 +465,7 @@
NS_LOG_LOGIC ("Restart PollRetransmit timer");
m_pollRetransmitTimer.Cancel ();
- m_pollRetransmitTimer = Simulator::Schedule (Time ("1.0s"),
+ m_pollRetransmitTimer = Simulator::Schedule (Time ("0.1s"),
&LteRlcAm::ExpirePollRetransmitTimer, this);
}
}
@@ -465,7 +478,7 @@
// 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 () ) = packet;
+ m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ) = packet;
// Send RLC PDU to MAC layer
LteMacSapProvider::TransmitPduParameters params;
@@ -544,7 +557,7 @@
// - update state variables and start t-Reordering as needed (see sub clause 5.1.3.2.4).
- uint16_t seqNumber = rlcAmHeader.GetSequenceNumber ();
+ SequenceNumber10 seqNumber = rlcAmHeader.GetSequenceNumber ();
if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::SEGMENT )
{
@@ -640,8 +653,8 @@
else
{
NS_LOG_LOGIC ("Place AMD PDU in the reception buffer ( SN = " << seqNumber << " )");
- m_rxonBuffer[ seqNumber ].m_byteSegments.push_back (p);
- m_rxonBuffer[ seqNumber ].m_pduComplete = true;
+ m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.push_back (p);
+ m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete = true;
// - if some byte segments of the AMD PDU contained in the RLC data PDU have been received before:
// - discard the duplicate byte segments.
@@ -656,7 +669,7 @@
if ( seqNumber >= m_vrH )
{
- m_vrH = (seqNumber + 1) % 1024;
+ m_vrH = seqNumber + 1;
NS_LOG_LOGIC ("New VR(H) = " << m_vrH);
}
@@ -664,11 +677,12 @@
// - update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for
// which not all byte segments have been received;
- if ( m_rxonBuffer[ m_vrMs ].m_pduComplete )
+ if ( m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
{
- while ( m_rxonBuffer[ m_vrMs ].m_pduComplete )
+ while ( m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
{
- m_vrMs = (m_vrMs + 1) % 1024;
+ m_vrMs++;
+ NS_LOG_LOGIC ("Incr VR(MS) = " << m_vrMs);
}
NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
}
@@ -681,21 +695,28 @@
if ( seqNumber == m_vrR )
{
- if ( m_rxonBuffer[ seqNumber ].m_pduComplete )
+ if ( m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete )
{
- while ( m_rxonBuffer[ m_vrR ].m_pduComplete )
+ while ( m_rxonBuffer[ m_vrR.GetValue () ].m_pduComplete )
{
- m_vrR = (m_vrR + 1) % 1024;
+ NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << m_vrR << " )");
+ NS_ASSERT_MSG (m_rxonBuffer[ m_vrR.GetValue () ].m_byteSegments.size () == 1,
+ "Too many segments. PDU Reassembly process didn't work");
+ ReassembleAndDeliver (m_rxonBuffer[ m_vrR.GetValue () ].m_byteSegments.front ());
+ m_rxonBuffer.erase (m_vrR.GetValue ());
+
+ m_vrR++;
}
NS_LOG_LOGIC ("New VR(R) = " << m_vrR);
m_vrMr = m_vrR + m_windowSize;
NS_LOG_LOGIC ("New VR(MR) = " << m_vrMr);
}
- NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << seqNumber << " )");
- NS_ASSERT_MSG (m_rxonBuffer[ seqNumber ].m_byteSegments.size () == 1,
- "Too many segments. PDU Reassembly process didn't work");
- ReassembleAndDeliver (m_rxonBuffer[ seqNumber ].m_byteSegments.front ());
+// NS_LOG_LOGIC ("Reassemble and Deliver ( SN = " << seqNumber << " )");
+// NS_ASSERT_MSG (m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.size () == 1,
+// "Too many segments. PDU Reassembly process didn't work");
+// ReassembleAndDeliver (m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.front ());
+// m_rxonBuffer.erase (seqNumber.GetValue ());
}
// - if t-Reordering is running:
@@ -727,7 +748,7 @@
if ( m_vrH > m_vrR )
{
NS_LOG_LOGIC ("Start reordering timer");
- m_reorderingTimer = Simulator::Schedule (Time ("1.0s"),
+ m_reorderingTimer = Simulator::Schedule (Time ("0.1s"),
&LteRlcAm::ExpireReorderingTimer ,this);
m_vrX = m_vrH;
NS_LOG_LOGIC ("New VR(X) = " << m_vrX);
@@ -831,46 +852,67 @@
{
NS_LOG_INFO ("Control AM RLC PDU");
- uint16_t ackSn = rlcAmHeader.GetAckSn ();
- uint16_t seqNumber = m_vtA;
+ SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
+// SequenceNumber10 seqNumber = m_vtA;
- while (seqNumber < ackSn)
+ NS_LOG_INFO ("ackSn = " << ackSn);
+ NS_LOG_INFO ("VT(A) = " << m_vtA);
+ NS_LOG_INFO ("VT(S) = " << m_vtS);
+ while (m_vtA < ackSn && m_vtA < m_vtS)
{
- NS_LOG_INFO ("seqNumber = " << seqNumber);
- NS_LOG_INFO ("ackSn = " << ackSn);
- NS_LOG_INFO ("m_txedBuffer(seqNumber).size = " << m_txedBuffer.size ());
- if (m_txedBuffer.at (seqNumber))
+// NS_LOG_INFO ("seqNumber = " << seqNumber);
+// NS_LOG_INFO ("m_txedBuffer( VT(A) ).size = " << m_txedBuffer.size ());
+
+ uint16_t seqNumberValue = m_vtA.GetValue ();
+ if (m_txedBuffer.at (seqNumberValue))
{
- NS_LOG_INFO ("m_txedBuffer(seqNumber)->GetSize = " << m_txedBuffer.at (seqNumber)->GetSize ());
- m_txedBufferSize -= m_txedBuffer.at (seqNumber)->GetSize ();
- m_txedBuffer.at (seqNumber) = 0;
+ NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from txedBuffer");
+// NS_LOG_INFO ("m_txedBuffer( " << m_vtA << " )->GetSize = " << m_txedBuffer.at (m_vtA.GetValue ())->GetSize ());
+ m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
+ m_txedBuffer.at (seqNumberValue) = 0;
}
- seqNumber++;
+
+ if (m_retxBuffer.at (seqNumberValue).m_pdu)
+ {
+ NS_LOG_INFO ("ACKed SN = " << seqNumberValue << " from retxBuffer");
+ m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
+ m_retxBuffer.at (seqNumberValue).m_pdu = 0;
+ m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
+ }
+
+ m_vtA++;
}
+ NS_LOG_INFO ("New VT(A) = " << m_vtA);
+
+ SequenceNumber10 seqNumber = m_vtA;
+ uint16_t seqNumberValue;
while (seqNumber < m_vtS)
{
- if (m_txedBuffer.at (seqNumber))
+ seqNumberValue = seqNumber.GetValue ();
+ if (m_txedBuffer.at (seqNumberValue))
{
- m_retxBuffer.at (seqNumber).m_pdu = m_txedBuffer.at (seqNumber);
- m_retxBuffer.at (seqNumber).m_retxCount = 0;
- m_retxBufferSize += m_retxBuffer.at (seqNumber).m_pdu->GetSize ();
+ NS_LOG_INFO ("Move SN = " << seqNumberValue << " to retxBuffer");
+ m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue);
+ m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
+ m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
- m_txedBufferSize -= m_txedBuffer.at (seqNumber)->GetSize ();
- m_txedBuffer.at (seqNumber) = 0;
+ m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
+ m_txedBuffer.at (seqNumberValue) = 0;
}
- else if (m_retxBuffer.at (seqNumber).m_pdu)
+ else if (m_retxBuffer.at (seqNumberValue).m_pdu)
{
- m_retxBuffer.at (seqNumber).m_retxCount++;
- if (m_retxBuffer.at (seqNumber).m_retxCount >= m_maxRetxThreshold)
+ m_retxBuffer.at (seqNumberValue).m_retxCount++;
+ NS_LOG_INFO ("Incr RETX_COUNT for SN = " << seqNumberValue);
+ if (m_retxBuffer.at (seqNumberValue).m_retxCount >= m_maxRetxThreshold)
{
- NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumber);
+ NS_LOG_INFO ("Max RETX_COUNT for SN = " << seqNumberValue);
}
}
seqNumber++;
}
-
+
return;
}
else
@@ -901,16 +943,24 @@
bool
-LteRlcAm::IsInsideReceivingWindow (uint16_t seqNumber)
+LteRlcAm::IsInsideReceivingWindow (SequenceNumber10 seqNumber)
{
- if ( ( ((m_vrR - m_vrR) % 1024) <= ((seqNumber - m_vrR) % 1024) ) &&
- ( ((seqNumber - m_vrR) % 1024) < ((m_vrMr - m_vrR) % 1024) )
- )
+ NS_LOG_FUNCTION (this << seqNumber);
+ NS_LOG_LOGIC ("Receiving Window: " <<
+ m_vrR << " <= " << seqNumber << " <= " << m_vrMr);
+
+ m_vrR.SetModulusBase (m_vrR);
+ m_vrMr.SetModulusBase (m_vrR);
+ seqNumber.SetModulusBase (m_vrR);
+
+ if ( (m_vrR <= seqNumber) && (seqNumber < m_vrMr ) )
{
+ NS_LOG_LOGIC (seqNumber << " is INSIDE the receiving window");
return true;
}
else
{
+ NS_LOG_LOGIC (seqNumber << " is OUTSIDE the receiving window");
return false;
}
}
@@ -922,20 +972,20 @@
LteRlcAmHeader rlcAmHeader;
packet->RemoveHeader (rlcAmHeader);
uint8_t framingInfo = rlcAmHeader.GetFramingInfo ();
- uint16_t currSeqNumber = rlcAmHeader.GetSequenceNumber ();
+ SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber ();
bool expectedSnLost;
if ( currSeqNumber != m_expectedSeqNumber )
{
expectedSnLost = true;
NS_LOG_LOGIC ("There are losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
- m_expectedSeqNumber = (currSeqNumber + 1) % 1024;
+ m_expectedSeqNumber = currSeqNumber + 1;
}
else
{
expectedSnLost = false;
NS_LOG_LOGIC ("No losses. Expected SN = " << m_expectedSeqNumber << ". Current SN = " << currSeqNumber);
- m_expectedSeqNumber = (m_expectedSeqNumber + 1) % 1024;
+ m_expectedSeqNumber = m_expectedSeqNumber + 1;
}
// Build list of SDUs
@@ -1387,7 +1437,6 @@
// }
-// TODO To check
void
LteRlcAm::ExpireReorderingTimer (void)
{
@@ -1402,23 +1451,22 @@
// - set VR(X) to VR(H).
m_vrMs = m_vrX;
- while ( m_rxonBuffer[ m_vrMs ].m_pduComplete )
+ while ( m_rxonBuffer[ m_vrMs.GetValue () ].m_pduComplete )
{
- m_vrMs = (m_vrMs + 1) % 1024;
+ m_vrMs++;
}
NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
if ( m_vrH > m_vrMs )
{
NS_LOG_LOGIC ("Start reordering timer");
- m_reorderingTimer = Simulator::Schedule (Time ("1.0s"),
+ m_reorderingTimer = Simulator::Schedule (Time ("0.1s"),
&LteRlcAm::ExpireReorderingTimer ,this);
m_vrX = m_vrH;
NS_LOG_LOGIC ("New VR(MS) = " << m_vrMs);
}
}
-// TODO To check
void
LteRlcAm::ExpirePollRetransmitTimer (void)
{
--- a/src/lte/model/lte-rlc-am.h Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/model/lte-rlc-am.h Wed Feb 08 17:14:58 2012 +0100
@@ -21,6 +21,8 @@
#ifndef LTE_RLC_AM_H
#define LTE_RLC_AM_H
+#include "ns3/lte-rlc-sequence-number.h"
+
#include "ns3/lte-rlc.h"
#include <vector>
@@ -61,7 +63,7 @@
void ExpireReorderingTimer (void);
void ExpirePollRetransmitTimer (void);
- bool IsInsideReceivingWindow (uint16_t seqNumber);
+ bool IsInsideReceivingWindow (SequenceNumber10 seqNumber);
//
// void ReassembleOutsideWindow (void);
// void ReassembleSnLessThan (uint16_t seqNumber);
@@ -89,7 +91,7 @@
struct PduBuffer
{
- uint16_t m_seqNumber;
+ SequenceNumber10 m_seqNumber;
std::list < Ptr<Packet> > m_byteSegments;
bool m_pduComplete;
@@ -110,17 +112,17 @@
* State variables. See section 7.1 in TS 36.322
*/
// Transmitting side
- uint16_t m_vtA; // VT(A)
- uint16_t m_vtMs; // VT(MS)
- uint16_t m_vtS; // VT(S)
- uint16_t m_pollSn; // POLL_SN
+ SequenceNumber10 m_vtA; // VT(A)
+ SequenceNumber10 m_vtMs; // VT(MS)
+ SequenceNumber10 m_vtS; // VT(S)
+ SequenceNumber10 m_pollSn; // POLL_SN
// Receiving side
- uint16_t m_vrR; // VR(R)
- uint16_t m_vrMr; // VR(MR)
- uint16_t m_vrX; // VR(X)
- uint16_t m_vrMs; // VR(MS)
- uint16_t m_vrH; // VR(H)
+ SequenceNumber10 m_vrR; // VR(R)
+ SequenceNumber10 m_vrMr; // VR(MR)
+ SequenceNumber10 m_vrX; // VR(X)
+ SequenceNumber10 m_vrMs; // VR(MS)
+ SequenceNumber10 m_vrH; // VR(H)
/**
* Counters. See section 7.1 in TS 36.322
@@ -159,7 +161,7 @@
/**
* Expected Sequence Number
*/
- uint16_t m_expectedSeqNumber;
+ SequenceNumber10 m_expectedSeqNumber;
};
--- a/src/lte/model/lte-rlc-sequence-number.h Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/model/lte-rlc-sequence-number.h Wed Feb 08 17:14:58 2012 +0100
@@ -125,6 +125,11 @@
return (!this->operator> (other));
}
+ bool operator >= (const SequenceNumber10 &other) const
+ {
+ return (this->operator> (other) || this->operator== (other));
+ }
+
bool operator < (const SequenceNumber10 &other) const
{
return !this->operator> (other) && m_value != other.m_value;
--- a/src/lte/model/lte-rlc-um.cc Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/model/lte-rlc-um.cc Wed Feb 08 17:14:58 2012 +0100
@@ -69,7 +69,7 @@
void
LteRlcUm::DoTransmitPdcpPdu (Ptr<Packet> p)
{
- NS_LOG_FUNCTION (this);
+ NS_LOG_FUNCTION (this << p->GetSize ());
/** Store arrival time */
RlcTag timeTag (Simulator::Now ());
@@ -488,6 +488,12 @@
ReassembleSnLessThan (m_vrUr);
}
+ // m_vrUh can change previously, set new modulus base
+ // for the t-Reordering timer-related comparisons
+ m_vrUr.SetModulusBase (m_vrUh - m_windowSize);
+ m_vrUx.SetModulusBase (m_vrUh - m_windowSize);
+ m_vrUh.SetModulusBase (m_vrUh - m_windowSize);
+
// - if t-Reordering is running:
// - if VR(UX) <= VR(UR); or
// - if VR(UX) falls outside of the reordering window and VR(UX) is not equal to VR(UH)::
@@ -512,11 +518,11 @@
{
NS_LOG_LOGIC ("Reordering timer is not running");
- if ( m_vrUx > m_vrUr )
+ if ( m_vrUh > m_vrUr )
{
- NS_LOG_LOGIC ("VR(UX) > VR(UR). " << m_vrUx << " > " << m_vrUr);
+ NS_LOG_LOGIC ("VR(UH) > VR(UR)");
NS_LOG_LOGIC ("Start reordering timer");
- m_reorderingTimer = Simulator::Schedule (Time ("1.0s"),
+ m_reorderingTimer = Simulator::Schedule (Time ("0.1s"),
&LteRlcUm::ExpireReorderingTimer ,this);
m_vrUx = m_vrUh;
NS_LOG_LOGIC ("New VR(UX) = " << m_vrUx);
@@ -547,12 +553,12 @@
if ( ((m_vrUh - m_windowSize) <= seqNumber) && (seqNumber < m_vrUh))
{
- NS_LOG_LOGIC (seqNumber << "is INSIDE the reordering window");
+ NS_LOG_LOGIC (seqNumber << " is INSIDE the reordering window");
return true;
}
else
{
- NS_LOG_LOGIC (seqNumber << "is OUTSIDE the reordering window");
+ NS_LOG_LOGIC (seqNumber << " is OUTSIDE the reordering window");
return false;
}
}
@@ -1062,7 +1068,7 @@
void
LteRlcUm::ExpireReorderingTimer (void)
{
- NS_LOG_LOGIC ("TODO: Reordering Timer has expired...");
+ NS_LOG_LOGIC ("Reordering timer has expired");
// 5.1.2.2.4 Actions when t-Reordering expires
// When t-Reordering expires, the receiving UM RLC entity shall:
@@ -1081,15 +1087,17 @@
newVrUr++;
}
m_vrUr = newVrUr;
+ NS_LOG_LOGIC ("New VR(UR) = " << m_vrUr);
ReassembleSnLessThan (m_vrUr);
if ( m_vrUh > m_vrUr)
{
NS_LOG_LOGIC ("Start reordering timer");
- m_reorderingTimer = Simulator::Schedule (Time ("1.0s"),
+ m_reorderingTimer = Simulator::Schedule (Time ("0.1s"),
&LteRlcUm::ExpireReorderingTimer, this);
m_vrUx = m_vrUh;
+ NS_LOG_LOGIC ("New VR(UX) = " << m_vrUx);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-simple-helper.cc Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,336 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es> (Based on lte-helper.cc)
+ */
+
+#include "ns3/lte-simple-helper.h"
+#include "ns3/log.h"
+#include "ns3/callback.h"
+#include "ns3/config.h"
+#include "ns3/simple-channel.h"
+#include "ns3/error-model.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("LteSimpleHelper");
+
+namespace ns3 {
+
+
+NS_OBJECT_ENSURE_REGISTERED (LteSimpleHelper);
+
+LteSimpleHelper::LteSimpleHelper (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_enbDeviceFactory.SetTypeId (LteSimpleNetDevice::GetTypeId ());
+ m_ueDeviceFactory.SetTypeId (LteSimpleNetDevice::GetTypeId ());
+}
+
+void
+LteSimpleHelper::DoStart (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ m_phyChannel = CreateObject<SimpleChannel> ();
+
+ Object::DoStart ();
+}
+
+LteSimpleHelper::~LteSimpleHelper (void)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+TypeId LteSimpleHelper::GetTypeId (void)
+{
+ static TypeId
+ tid =
+ TypeId ("ns3::LteSimpleHelper")
+ .SetParent<Object> ()
+ .AddConstructor<LteSimpleHelper> ()
+ .AddAttribute ("RlcEntity",
+ "Specify which type of RLC will be used. ",
+ EnumValue (RLC_UM),
+ MakeEnumAccessor (&LteSimpleHelper::m_lteRlcEntityType),
+ MakeEnumChecker (RLC_UM, "RlcUm",
+ RLC_AM, "RlcAm"))
+ ;
+ return tid;
+}
+
+void
+LteSimpleHelper::DoDispose ()
+{
+ NS_LOG_FUNCTION (this);
+ m_phyChannel = 0;
+
+ m_enbMac->Dispose ();
+ m_enbMac = 0;
+ m_ueMac->Dispose ();
+ m_ueMac = 0;
+
+ Object::DoDispose ();
+}
+
+
+NetDeviceContainer
+LteSimpleHelper::InstallEnbDevice (NodeContainer c)
+{
+ NS_LOG_FUNCTION (this);
+ Start (); // will run DoStart () if necessary
+ NetDeviceContainer devices;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<NetDevice> device = InstallSingleEnbDevice (node);
+ devices.Add (device);
+ }
+ return devices;
+}
+
+NetDeviceContainer
+LteSimpleHelper::InstallUeDevice (NodeContainer c)
+{
+ NS_LOG_FUNCTION (this);
+ NetDeviceContainer devices;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<NetDevice> device = InstallSingleUeDevice (node);
+ devices.Add (device);
+ }
+ return devices;
+}
+
+
+Ptr<NetDevice>
+LteSimpleHelper::InstallSingleEnbDevice (Ptr<Node> n)
+{
+ NS_LOG_FUNCTION (this);
+
+ m_enbRrc = CreateObject<LteTestRrc> ();
+ m_enbPdcp = CreateObject<LtePdcp> ();
+
+ if (m_lteRlcEntityType == RLC_UM)
+ {
+ m_enbRlc = CreateObject<LteRlcUm> ();
+ }
+ else // m_lteRlcEntityType == RLC_AM
+ {
+ m_enbRlc = CreateObject<LteRlcAm> ();
+ }
+
+ m_enbRlc->SetRnti (11);
+ m_enbRlc->SetLcId (12);
+
+ Ptr<LteSimpleNetDevice> enbDev = m_enbDeviceFactory.Create<LteSimpleNetDevice> ();
+ enbDev->SetAddress (Mac48Address::Allocate ());
+ enbDev->SetChannel (m_phyChannel);
+
+ n->AddDevice (enbDev);
+
+ m_enbMac = CreateObject<LteTestMac> ();
+ m_enbMac->SetDevice (enbDev);
+
+ enbDev->SetReceiveCallback (MakeCallback (&LteTestMac::Receive, m_enbMac));
+
+ // Connect SAPs: RRC <-> PDCP <-> RLC <-> MAC
+
+ m_enbRrc->SetLtePdcpSapProvider (m_enbPdcp->GetLtePdcpSapProvider ());
+ m_enbPdcp->SetLtePdcpSapUser (m_enbRrc->GetLtePdcpSapUser ());
+
+ m_enbPdcp->SetLteRlcSapProvider (m_enbRlc->GetLteRlcSapProvider ());
+ m_enbRlc->SetLteRlcSapUser (m_enbPdcp->GetLteRlcSapUser ());
+
+ m_enbRlc->SetLteMacSapProvider (m_enbMac->GetLteMacSapProvider ());
+ m_enbMac->SetLteMacSapUser (m_enbRlc->GetLteMacSapUser ());
+
+ return enbDev;
+}
+
+Ptr<NetDevice>
+LteSimpleHelper::InstallSingleUeDevice (Ptr<Node> n)
+{
+ NS_LOG_FUNCTION (this);
+
+ m_ueRrc = CreateObject<LteTestRrc> ();
+ m_uePdcp = CreateObject<LtePdcp> ();
+
+ if (m_lteRlcEntityType == RLC_UM)
+ {
+ m_ueRlc = CreateObject<LteRlcUm> ();
+ }
+ else // m_lteRlcEntityType == RLC_AM
+ {
+ m_ueRlc = CreateObject<LteRlcAm> ();
+ }
+
+ m_ueRlc->SetRnti (21);
+ m_ueRlc->SetLcId (22);
+
+ Ptr<LteSimpleNetDevice> ueDev = m_ueDeviceFactory.Create<LteSimpleNetDevice> ();
+ ueDev->SetAddress (Mac48Address::Allocate ());
+ ueDev->SetChannel (m_phyChannel);
+
+ n->AddDevice (ueDev);
+
+ m_ueMac = CreateObject<LteTestMac> ();
+ m_ueMac->SetDevice (ueDev);
+
+ ueDev->SetReceiveCallback (MakeCallback (&LteTestMac::Receive, m_ueMac));
+
+ // Connect SAPs: RRC <-> PDCP <-> RLC <-> MAC
+
+ m_ueRrc->SetLtePdcpSapProvider (m_uePdcp->GetLtePdcpSapProvider ());
+ m_uePdcp->SetLtePdcpSapUser (m_ueRrc->GetLtePdcpSapUser ());
+
+ m_uePdcp->SetLteRlcSapProvider (m_ueRlc->GetLteRlcSapProvider ());
+ m_ueRlc->SetLteRlcSapUser (m_uePdcp->GetLteRlcSapUser ());
+
+ m_ueRlc->SetLteMacSapProvider (m_ueMac->GetLteMacSapProvider ());
+ m_ueMac->SetLteMacSapUser (m_ueRlc->GetLteMacSapUser ());
+
+ return ueDev;
+}
+
+
+void
+LteSimpleHelper::EnableLogComponents (void)
+{
+ LogLevel level = (LogLevel) (LOG_LEVEL_ALL | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_PREFIX_FUNC);
+
+ LogComponentEnable ("Config", level);
+ LogComponentEnable ("LteSimpleHelper", level);
+ LogComponentEnable ("LteTestEntities", level);
+ LogComponentEnable ("LtePdcp", level);
+ LogComponentEnable ("LteRlc", level);
+ LogComponentEnable ("LteRlcUm", level);
+ LogComponentEnable ("LteRlcAm", level);
+ LogComponentEnable ("LteSimpleNetDevice", level);
+ LogComponentEnable ("SimpleNetDevice", level);
+ LogComponentEnable ("SimpleChannel", level);
+}
+
+void
+LteSimpleHelper::EnableTraces (void)
+{
+// EnableMacTraces ();
+ EnableRlcTraces ();
+ EnablePdcpTraces ();
+}
+
+void
+LteSimpleHelper::EnableRlcTraces (void)
+{
+ EnableDlRlcTraces ();
+ EnableUlRlcTraces ();
+}
+
+
+void
+LteSimpleHelperDlTxPduCallback (Ptr<RadioBearerStatsCalculator> rlcStats, std::string path,
+ uint16_t rnti, uint8_t lcid, uint32_t packetSize)
+{
+ NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize);
+ uint64_t imsi = 111;
+ uint16_t cellId = 222;
+ rlcStats->DlTxPdu (cellId, imsi, rnti, lcid, packetSize);
+}
+
+void
+LteSimpleHelperDlRxPduCallback (Ptr<RadioBearerStatsCalculator> rlcStats, std::string path,
+ uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
+{
+ NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize << delay);
+ uint64_t imsi = 333;
+ rlcStats->DlRxPdu (imsi, rnti, lcid, packetSize, delay);
+}
+
+void
+LteSimpleHelper::EnableDlRlcTraces (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ // Config::Connect ("/NodeList/*/DeviceList/*/LteRlc/TxPDU",
+ // MakeBoundCallback (&LteSimpleHelperDlTxPduCallback, m_rlcStats));
+ // Config::Connect ("/NodeList/*/DeviceList/*/LteRlc/RxPDU",
+ // MakeBoundCallback (&LteSimpleHelperDlRxPduCallback, m_rlcStats));
+}
+
+void
+LteSimpleHelperUlTxPduCallback (Ptr<RadioBearerStatsCalculator> rlcStats, std::string path,
+ uint16_t rnti, uint8_t lcid, uint32_t packetSize)
+{
+ NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize);
+ uint64_t imsi = 1111;
+ rlcStats->UlTxPdu (imsi, rnti, lcid, packetSize);
+}
+
+void
+LteSimpleHelperUlRxPduCallback (Ptr<RadioBearerStatsCalculator> rlcStats, std::string path,
+ uint16_t rnti, uint8_t lcid, uint32_t packetSize, uint64_t delay)
+{
+ NS_LOG_FUNCTION (rlcStats << path << rnti << (uint16_t)lcid << packetSize << delay);
+ uint64_t imsi = 444;
+ uint16_t cellId = 555;
+ rlcStats->UlRxPdu (cellId, imsi, rnti, lcid, packetSize, delay);
+}
+
+
+void
+LteSimpleHelper::EnableUlRlcTraces (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ // Config::Connect ("/NodeList/*/DeviceList/*/LteRlc/TxPDU",
+ // MakeBoundCallback (&LteSimpleHelperUlTxPduCallback, m_rlcStats));
+ // Config::Connect ("/NodeList/*/DeviceList/*/LteRlc/RxPDU",
+ // MakeBoundCallback (&LteSimpleHelperUlRxPduCallback, m_rlcStats));
+}
+
+
+void
+LteSimpleHelper::EnablePdcpTraces (void)
+{
+ EnableDlPdcpTraces ();
+ EnableUlPdcpTraces ();
+}
+
+void
+LteSimpleHelper::EnableDlPdcpTraces (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ // Config::Connect ("/NodeList/*/DeviceList/*/LtePdcp/TxPDU",
+ // MakeBoundCallback (&LteSimpleHelperDlTxPduCallback, m_pdcpStats));
+ // Config::Connect ("/NodeList/*/DeviceList/*/LtePdcp/RxPDU",
+ // MakeBoundCallback (&LteSimpleHelperDlRxPduCallback, m_pdcpStats));
+}
+
+void
+LteSimpleHelper::EnableUlPdcpTraces (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ // Config::Connect ("/NodeList/*/DeviceList/*/LtePdcp/TxPDU",
+ // MakeBoundCallback (&LteSimpleHelperUlTxPduCallback, m_pdcpStats));
+ // Config::Connect ("/NodeList/*/DeviceList/*/LtePdcp/RxPDU",
+ // MakeBoundCallback (&LteSimpleHelperUlRxPduCallback, m_pdcpStats));
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-simple-helper.h Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,154 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es> (Based on lte-helper.h)
+ */
+
+#ifndef LTE_SIMPLE_HELPER_H
+#define LTE_SIMPLE_HELPER_H
+
+#include "ns3/net-device-container.h"
+#include "ns3/simple-channel.h"
+#include "ns3/node-container.h"
+#include "ns3/radio-bearer-stats-calculator.h"
+#include "ns3/lte-simple-net-device.h"
+
+#include "ns3/lte-test-entities.h"
+#include "ns3/lte-pdcp.h"
+#include "ns3/lte-rlc.h"
+#include "ns3/lte-rlc-um.h"
+#include "ns3/lte-rlc-am.h"
+
+namespace ns3 {
+
+
+/**
+ * Creation and configuration of LTE entities
+ *
+ */
+class LteSimpleHelper : public Object
+{
+public:
+ LteSimpleHelper (void);
+ virtual ~LteSimpleHelper (void);
+
+ static TypeId GetTypeId (void);
+ virtual void DoDispose (void);
+
+
+ /**
+ * create a set of eNB devices
+ *
+ * \param c the node container where the devices are to be installed
+ *
+ * \return the NetDeviceContainer with the newly created devices
+ */
+ NetDeviceContainer InstallEnbDevice (NodeContainer c);
+
+ /**
+ * create a set of UE devices
+ *
+ * \param c the node container where the devices are to be installed
+ *
+ * \return the NetDeviceContainer with the newly created devices
+ */
+ NetDeviceContainer InstallUeDevice (NodeContainer c);
+
+
+ /**
+ * Enables logging for all components of the LENA architecture
+ *
+ */
+ void EnableLogComponents (void);
+
+ /**
+ * Enables trace sinks for MAC, RLC and PDCP
+ */
+ void EnableTraces (void);
+
+
+ /**
+ * Enable trace sinks for RLC layer
+ */
+ void EnableRlcTraces (void);
+
+ /**
+ * Enable trace sinks for DL RLC layer
+ */
+ void EnableDlRlcTraces (void);
+
+ /**
+ * Enable trace sinks for UL RLC layer
+ */
+ void EnableUlRlcTraces (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 PDCP layer
+ */
+ void EnableUlPdcpTraces (void);
+
+
+protected:
+ // inherited from Object
+ virtual void DoStart (void);
+
+private:
+ Ptr<NetDevice> InstallSingleEnbDevice (Ptr<Node> n);
+ Ptr<NetDevice> InstallSingleUeDevice (Ptr<Node> n);
+
+ Ptr<SimpleChannel> m_phyChannel;
+
+public:
+
+ Ptr<LteTestRrc> m_enbRrc;
+ Ptr<LteTestRrc> m_ueRrc;
+
+ Ptr<LteTestMac> m_enbMac;
+ Ptr<LteTestMac> m_ueMac;
+
+private:
+
+ Ptr<LtePdcp> m_enbPdcp;
+ Ptr<LteRlc> m_enbRlc;
+
+ Ptr<LtePdcp> m_uePdcp;
+ Ptr<LteRlc> m_ueRlc;
+
+ ObjectFactory m_enbDeviceFactory;
+ ObjectFactory m_ueDeviceFactory;
+
+ enum LteRlcEntityType_t {RLC_UM = 1,
+ RLC_AM = 2 } m_lteRlcEntityType;
+
+};
+
+
+} // namespace ns3
+
+
+#endif // LTE_SIMPLE_HELPER_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-simple-net-device.cc Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#include "ns3/simulator.h"
+#include "ns3/pointer.h"
+#include "ns3/log.h"
+#include "ns3/lte-simple-net-device.h"
+
+NS_LOG_COMPONENT_DEFINE ("LteSimpleNetDevice");
+
+namespace ns3 {
+
+
+NS_OBJECT_ENSURE_REGISTERED (LteSimpleNetDevice);
+
+
+TypeId LteSimpleNetDevice::GetTypeId (void)
+{
+ static TypeId
+ tid =
+ TypeId ("ns3::LteSimpleNetDevice")
+ .SetParent<SimpleNetDevice> ()
+ .AddConstructor<LteSimpleNetDevice> ()
+ ;
+
+ return tid;
+}
+
+
+LteSimpleNetDevice::LteSimpleNetDevice (void)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+
+LteSimpleNetDevice::LteSimpleNetDevice (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this);
+ SetNode (node);
+}
+
+LteSimpleNetDevice::~LteSimpleNetDevice (void)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+LteSimpleNetDevice::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+ SimpleNetDevice::DoDispose ();
+}
+
+
+void
+LteSimpleNetDevice::DoStart (void)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+bool
+LteSimpleNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+{
+ NS_LOG_FUNCTION (this << dest << protocolNumber);
+ return SimpleNetDevice::Send (packet, dest, protocolNumber);
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-simple-net-device.h Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#ifndef LTE_SIMPLE_NET_DEVICE_H
+#define LTE_SIMPLE_NET_DEVICE_H
+
+#include "ns3/event-id.h"
+#include "ns3/node.h"
+#include "ns3/error-model.h"
+#include "ns3/simple-channel.h"
+#include "ns3/simple-net-device.h"
+#include "ns3/lte-rlc.h"
+
+namespace ns3 {
+
+
+/**
+ * \ingroup lte
+ * The LteSimpleNetDevice class implements the LTE simple net device
+ */
+class LteSimpleNetDevice : public SimpleNetDevice
+{
+
+public:
+ static TypeId GetTypeId (void);
+
+ LteSimpleNetDevice (void);
+ LteSimpleNetDevice (Ptr<Node> node);
+
+ virtual ~LteSimpleNetDevice (void);
+ virtual void DoDispose ();
+
+
+ // inherited from NetDevice
+ virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
+
+
+protected:
+ // inherited from Object
+ virtual void DoStart (void);
+
+};
+
+} // namespace ns3
+
+
+#endif // LTE_SIMPLE_NET_DEVICE_H
--- a/src/lte/test/lte-test-entities.cc Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/test/lte-test-entities.cc Wed Feb 08 17:14:58 2012 +0100
@@ -48,8 +48,14 @@
LteTestRrc::LteTestRrc ()
{
NS_LOG_FUNCTION (this);
+
+ m_txPdus = 0;
+ m_txBytes = 0;
+ m_rxPdus = 0;
+ m_rxBytes = 0;
+
m_pdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteTestRrc> (this);
- Simulator::ScheduleNow (&LteTestRrc::Start, this);
+// Simulator::ScheduleNow (&LteTestRrc::Start, this);
}
LteTestRrc::~LteTestRrc ()
@@ -81,8 +87,51 @@
LteTestRrc::GetDataReceived (void)
{
NS_LOG_FUNCTION (this);
+ return m_receivedData;
+}
- return m_receivedData;
+// Stats
+uint32_t
+LteTestRrc::GetTxPdus (void)
+{
+ NS_LOG_FUNCTION (this << m_txPdus);
+ return m_txPdus;
+}
+
+uint32_t
+LteTestRrc::GetTxBytes (void)
+{
+ NS_LOG_FUNCTION (this << m_txBytes);
+ return m_txBytes;
+}
+
+uint32_t
+LteTestRrc::GetRxPdus (void)
+{
+ NS_LOG_FUNCTION (this << m_rxPdus);
+ return m_rxPdus;
+}
+
+uint32_t
+LteTestRrc::GetRxBytes (void)
+{
+ NS_LOG_FUNCTION (this << m_rxBytes);
+ return m_rxBytes;
+}
+
+
+void
+LteTestRrc::SetArrivalTime (Time arrivalTime)
+{
+ NS_LOG_FUNCTION (this << arrivalTime);
+ m_arrivalTime = arrivalTime;
+}
+
+void
+LteTestRrc::SetPduSize (uint32_t pduSize)
+{
+ NS_LOG_FUNCTION (this << pduSize);
+ m_pduSize = pduSize;
}
@@ -95,14 +144,19 @@
{
NS_LOG_FUNCTION (this << params.rrcPdu->GetSize ());
Ptr<Packet> p = params.rrcPdu;
- NS_LOG_LOGIC ("PDU received = " << (*p));
+// NS_LOG_LOGIC ("PDU received = " << (*p));
uint32_t dataLen = p->GetSize ();
uint8_t *buf = new uint8_t[dataLen];
+
+ // Stats
+ m_rxPdus++;
+ m_rxBytes += dataLen;
+
p->CopyData (buf, dataLen);
m_receivedData = std::string ((char *)buf, dataLen);
- NS_LOG_LOGIC (m_receivedData);
+// NS_LOG_LOGIC (m_receivedData);
delete [] buf;
}
@@ -115,6 +169,27 @@
LteTestRrc::Start ()
{
NS_LOG_FUNCTION (this);
+ NS_ASSERT_MSG (m_arrivalTime != 0, "Arrival time must be different from 0");
+
+ // Stats
+ m_txPdus++;
+ m_txBytes += m_pduSize;
+
+ LtePdcpSapProvider::TransmitRrcPduParameters p;
+ p.rnti = 1111;
+ p.lcid = 222;
+ p.rrcPdu = Create<Packet> (m_pduSize);
+
+ Simulator::ScheduleNow (&LtePdcpSapProvider::TransmitRrcPdu, m_pdcpSapProvider, p);
+ m_nextPdu = Simulator::Schedule (m_arrivalTime, &LteTestRrc::Start, this);
+// Simulator::Run ();
+}
+
+void
+LteTestRrc::Stop ()
+{
+ NS_LOG_FUNCTION (this);
+ m_nextPdu.Cancel ();
}
void
@@ -122,11 +197,18 @@
{
NS_LOG_FUNCTION (this << at << dataToSend.length () << dataToSend);
+ // Stats
+ m_txPdus++;
+ m_txBytes += dataToSend.length ();
+
LtePdcpSapProvider::TransmitRrcPduParameters p;
p.rnti = 1111;
p.lcid = 222;
+ NS_LOG_LOGIC ("Data(" << dataToSend.length () << ") = " << dataToSend.data ());
p.rrcPdu = Create<Packet> ((uint8_t *) dataToSend.data (), dataToSend.length ());
+
+ NS_LOG_LOGIC ("Packet(" << p.rrcPdu->GetSize () << ")");
Simulator::Schedule (at, &LtePdcpSapProvider::TransmitRrcPdu, m_pdcpSapProvider, p);
}
@@ -223,7 +305,10 @@
p.rnti = 1111;
p.lcid = 222;
+ NS_LOG_LOGIC ("Data(" << dataToSend.length () << ") = " << dataToSend.data ());
p.pdcpPdu = Create<Packet> ((uint8_t *) dataToSend.data (), dataToSend.length ());
+
+ NS_LOG_LOGIC ("Packet(" << p.pdcpPdu->GetSize () << ")");
Simulator::Schedule (time, &LteRlcSapProvider::TransmitPdcpPdu, m_rlcSapProvider, p);
}
@@ -243,12 +328,21 @@
LteTestMac::LteTestMac ()
{
NS_LOG_FUNCTION (this);
+ m_device = 0;
m_macSapProvider = new EnbMacMemberLteMacSapProvider<LteTestMac> (this);
m_macSapUser = 0;
m_macLoopback = 0;
m_pdcpHeaderPresent = false;
m_rlcHeaderType = UM_RLC_HEADER;
m_txOpportunityMode = MANUAL_MODE;
+ m_txOppTime = Seconds (0.001);
+ m_txOppSize = 0;
+
+ m_txPdus = 0;
+ m_txBytes = 0;
+ m_rxPdus = 0;
+ m_rxBytes = 0;
+
// m_cmacSapProvider = new EnbMacMemberLteEnbCmacSapProvider (this);
// m_schedSapUser = new EnbMacMemberFfMacSchedSapUser (this);
// m_cschedSapUser = new EnbMacMemberFfMacCschedSapUser (this);
@@ -269,6 +363,14 @@
// delete m_schedSapUser;
// delete m_cschedSapUser;
// delete m_enbPhySapUser;
+
+ m_device = 0;
+}
+
+void
+LteTestMac::SetDevice (Ptr<NetDevice> device)
+{
+ m_device = device;
}
void
@@ -293,37 +395,94 @@
LteTestMac::GetDataReceived (void)
{
NS_LOG_FUNCTION (this);
-
return m_receivedData;
}
+// Stats
+uint32_t
+LteTestMac::GetTxPdus (void)
+{
+ NS_LOG_FUNCTION (this << m_txPdus);
+ return m_txPdus;
+}
+
+uint32_t
+LteTestMac::GetTxBytes (void)
+{
+ NS_LOG_FUNCTION (this << m_txBytes);
+ return m_txBytes;
+}
+
+uint32_t
+LteTestMac::GetRxPdus (void)
+{
+ NS_LOG_FUNCTION (this << m_rxPdus);
+ return m_rxPdus;
+}
+
+uint32_t
+LteTestMac::GetRxBytes (void)
+{
+ NS_LOG_FUNCTION (this << m_rxBytes);
+ return m_rxBytes;
+}
+
+
void
LteTestMac::SendTxOpportunity (Time time, uint32_t bytes)
{
NS_LOG_FUNCTION (this << time << bytes);
-
Simulator::Schedule (time, &LteMacSapUser::NotifyTxOpportunity, m_macSapUser, bytes);
+ if (m_txOpportunityMode == RANDOM_MODE)
+ {
+ if (m_txOppTime != Seconds (0))
+ {
+ Simulator::Schedule (m_txOppTime, &LteTestMac::SendTxOpportunity, this, m_txOppTime, m_txOppSize);
+ }
+ }
}
void
LteTestMac::SetPdcpHeaderPresent (bool present)
{
- NS_LOG_FUNCTION (this);
+ NS_LOG_FUNCTION (this << present);
m_pdcpHeaderPresent = present;
}
void
LteTestMac::SetRlcHeaderType (uint8_t rlcHeaderType)
{
- NS_LOG_FUNCTION (this);
+ NS_LOG_FUNCTION (this << rlcHeaderType);
m_rlcHeaderType = rlcHeaderType;
}
void
LteTestMac::SetTxOpportunityMode (uint8_t mode)
{
- NS_LOG_FUNCTION (this);
+ NS_LOG_FUNCTION (this << (uint32_t)mode);
m_txOpportunityMode = mode;
+
+ if (m_txOpportunityMode == RANDOM_MODE)
+ {
+ if (m_txOppTime != Seconds (0.0))
+ {
+ SendTxOpportunity (m_txOppTime, m_txOppSize);
+ }
+ }
+}
+
+void
+LteTestMac::SetTxOppTime (Time txOppTime)
+{
+ NS_LOG_FUNCTION (this << txOppTime);
+ m_txOppTime = txOppTime;
+}
+
+void
+LteTestMac::SetTxOppSize (uint32_t txOppSize)
+{
+ NS_LOG_FUNCTION (this << txOppSize);
+ m_txOppSize = txOppSize;
}
@@ -336,46 +495,51 @@
{
NS_LOG_FUNCTION (this << params.pdu->GetSize ());
- if (m_macLoopback)
- {
- Simulator::Schedule (Seconds (0.1), &LteMacSapUser::ReceivePdu,
- m_macLoopback->m_macSapUser, params.pdu);
- }
- else
- {
- LtePdcpHeader pdcpHeader;
+ m_txPdus++;
+ m_txBytes += params.pdu->GetSize ();
+
+ m_device->Send (params.pdu, m_device->GetBroadcast (), 0);
- if (m_rlcHeaderType == AM_RLC_HEADER)
- {
- // Remove AM RLC header
- LteRlcAmHeader rlcAmHeader;
- params.pdu->RemoveHeader (rlcAmHeader);
- NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader);
- }
- else // if (m_rlcHeaderType == UM_RLC_HEADER)
- {
- // Remove UM RLC header
- LteRlcHeader rlcHeader;
- params.pdu->RemoveHeader (rlcHeader);
- NS_LOG_LOGIC ("UM RLC header: " << rlcHeader);
- }
-
- // Remove PDCP header, if present
- if (m_pdcpHeaderPresent)
- {
- params.pdu->RemoveHeader (pdcpHeader);
- NS_LOG_LOGIC ("PDCP header: " << pdcpHeader);
- }
-
- // 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 = " << m_receivedData);
- delete [] buf;
- }
+// if (m_macLoopback)
+// {
+// Simulator::Schedule (Seconds (0.1), &LteMacSapUser::ReceivePdu,
+// m_macLoopback->m_macSapUser, params.pdu);
+// }
+// else
+// {
+// LtePdcpHeader pdcpHeader;
+//
+// if (m_rlcHeaderType == AM_RLC_HEADER)
+// {
+// // Remove AM RLC header
+// LteRlcAmHeader rlcAmHeader;
+// params.pdu->RemoveHeader (rlcAmHeader);
+// NS_LOG_LOGIC ("AM RLC header: " << rlcAmHeader);
+// }
+// else // if (m_rlcHeaderType == UM_RLC_HEADER)
+// {
+// // Remove UM RLC header
+// LteRlcHeader rlcHeader;
+// params.pdu->RemoveHeader (rlcHeader);
+// NS_LOG_LOGIC ("UM RLC header: " << rlcHeader);
+// }
+//
+// // Remove PDCP header, if present
+// if (m_pdcpHeaderPresent)
+// {
+// params.pdu->RemoveHeader (pdcpHeader);
+// NS_LOG_LOGIC ("PDCP header: " << pdcpHeader);
+// }
+//
+// // 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;
+// }
}
void
@@ -401,5 +565,18 @@
m_macSapUser, params.retxQueueSize + 2);
}
}
+}
+
+bool
+LteTestMac::Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr)
+{
+ NS_LOG_FUNCTION (this << addr << protocol << p->GetSize ());
+
+ m_rxPdus++;
+ m_rxBytes += p->GetSize ();
+
+ Ptr<Packet> packet = p->Copy ();
+ m_macSapUser->ReceivePdu (packet);
+ return true;
}
--- a/src/lte/test/lte-test-entities.h Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/test/lte-test-entities.h Wed Feb 08 17:14:58 2012 +0100
@@ -21,6 +21,7 @@
#ifndef LTE_TEST_ENTITIES_H
#define LTE_TEST_ENTITIES_H
+#include "ns3/simulator.h"
#include "ns3/test.h"
// #include "ns3/type-id.h"
@@ -28,6 +29,7 @@
#include "ns3/lte-rlc-sap.h"
#include "ns3/lte-pdcp-sap.h"
+#include "ns3/net-device.h"
using namespace ns3;
@@ -64,10 +66,20 @@
LtePdcpSapUser* GetLtePdcpSapUser (void);
void Start ();
+ void Stop ();
void SendData (Time at, std::string dataToSend);
std::string GetDataReceived (void);
+ // Stats
+ uint32_t GetTxPdus (void);
+ uint32_t GetTxBytes (void);
+ uint32_t GetRxPdus (void);
+ uint32_t GetRxBytes (void);
+
+ void SetArrivalTime (Time arrivalTime);
+ void SetPduSize (uint32_t pduSize);
+
private:
// Interface forwarded by LtePdcpSapUser
virtual void DoReceiveRrcPdu (LtePdcpSapUser::ReceiveRrcPduParameters params);
@@ -77,6 +89,14 @@
std::string m_receivedData;
+ uint32_t m_txPdus;
+ uint32_t m_txBytes;
+ uint32_t m_rxPdus;
+ uint32_t m_rxBytes;
+
+ EventId m_nextPdu;
+ Time m_arrivalTime;
+ uint32_t m_pduSize;
};
/////////////////////////////////////////////////////////////////////
@@ -125,7 +145,6 @@
LteRlcSapProvider* m_rlcSapProvider;
std::string m_receivedData;
-
};
/////////////////////////////////////////////////////////////////////
@@ -148,9 +167,13 @@
virtual ~LteTestMac (void);
virtual void DoDispose (void);
- void SendTxOpportunity (Time time, uint32_t bytes);
+ void SetDevice (Ptr<NetDevice> device);
+
+ void SendTxOpportunity (Time, uint32_t);
std::string GetDataReceived (void);
+ bool Receive (Ptr<NetDevice> nd, Ptr<const Packet> p, uint16_t protocol, const Address& addr);
+
/**
* \brief Set the MAC SAP user
* \param s a pointer to the MAC SAP user
@@ -190,9 +213,19 @@
typedef enum {
MANUAL_MODE = 0,
- AUTOMATIC_MODE = 1
+ AUTOMATIC_MODE = 1,
+ RANDOM_MODE = 2
} TxOpportunityMode_t;
+ void SetTxOppTime (Time txOppTime);
+ void SetTxOppSize (uint32_t txOppSize);
+
+ // Stats
+ uint32_t GetTxPdus (void);
+ uint32_t GetTxBytes (void);
+ uint32_t GetRxPdus (void);
+ uint32_t GetRxBytes (void);
+
private:
// forwarded from LteMacSapProvider
void DoTransmitPdu (LteMacSapProvider::TransmitPduParameters);
@@ -206,7 +239,20 @@
uint8_t m_rlcHeaderType;
bool m_pdcpHeaderPresent;
- bool m_txOpportunityMode;
+ uint8_t m_txOpportunityMode;
+
+ Ptr<NetDevice> m_device;
+
+ // TxOpportunity configuration
+ EventId m_nextTxOpp;
+ Time m_txOppTime;
+ uint32_t m_txOppSize;
+
+ // Stats
+ uint32_t m_txPdus;
+ uint32_t m_txBytes;
+ uint32_t m_rxPdus;
+ uint32_t m_rxBytes;
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-rlc-am-e2e.cc Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/pointer.h"
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/lte-simple-helper.h"
+#include "ns3/error-model.h"
+
+#include "ns3/radio-bearer-stats-calculator.h"
+
+#include "ns3/lte-rlc-header.h"
+#include "ns3/lte-rlc-um.h"
+
+#include "ns3/lte-test-entities.h"
+#include "ns3/lte-test-rlc-am-e2e.h"
+
+#include "ns3/config-store.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("LteRlcAmE2eTest");
+
+using namespace ns3;
+
+
+/**
+ * Test x.x.x RLC AM: End-to-end flow
+ */
+
+/**
+ * TestSuite
+ */
+
+LteRlcAmE2eTestSuite::LteRlcAmE2eTestSuite ()
+ : TestSuite ("lte-rlc-am-e2e", SYSTEM)
+{
+ // NS_LOG_INFO ("Creating LteRlcAmE2eTestSuite");
+
+ double losses[] = {0.0, 0.10, 0.25, 0.50, 0.75, 0.90, 0.95};
+ uint32_t seeds[] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 10101};
+
+ for ( uint32_t l = 0 ; l < (sizeof (losses) / sizeof (double)) ; l++ )
+ {
+ for ( uint32_t s = 0 ; s < (sizeof (seeds) / sizeof (uint32_t)) ; s++ )
+ {
+ std::ostringstream name;
+ name << " Losses = " << losses[l] << "%. Seed = " << seeds[s];
+ AddTestCase (new LteRlcAmE2eTestCase (name.str (), seeds[s], losses[l]));
+ }
+ }
+}
+
+static LteRlcAmE2eTestSuite lteRlcAmE2eTestSuite;
+
+
+/**
+ * TestCase
+ */
+
+LteRlcAmE2eTestCase::LteRlcAmE2eTestCase (std::string name, uint32_t seed, double losses)
+ : TestCase (name)
+{
+ // NS_LOG_UNCOND ("Creating LteRlcAmTestingTestCase: " + name);
+
+ m_seed = seed;
+ m_losses = losses;
+
+ m_dlDrops = 0;
+ m_ulDrops = 0;
+}
+
+LteRlcAmE2eTestCase::~LteRlcAmE2eTestCase ()
+{
+}
+
+
+void
+LteRlcAmE2eTestCase::DlDropEvent (Ptr<const Packet> p)
+{
+ // NS_LOG_FUNCTION (this);
+ m_dlDrops++;
+}
+
+void
+LteRlcAmE2eTestCase::UlDropEvent (Ptr<const Packet> p)
+{
+ // NS_LOG_FUNCTION (this);
+ m_ulDrops++;
+}
+
+void
+LteRlcAmE2eTestCase::DoRun (void)
+{
+ uint16_t numberOfNodes = 1;
+
+ LogLevel level = (LogLevel) (LOG_LEVEL_ALL | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_PREFIX_FUNC);
+ LogComponentEnable ("LteRlcAmE2eTest", level);
+ // LogComponentEnable ("ErrorModel", level);
+ // LogComponentEnable ("LteSimpleHelper", level);
+ // LogComponentEnable ("LteSimpleNetDevice", level);
+ // LogComponentEnable ("SimpleNetDevice", level);
+ // LogComponentEnable ("SimpleChannel", level);
+ // LogComponentEnable ("LteTestEntities", level);
+ // LogComponentEnable ("LtePdcp", level);
+ // LogComponentEnable ("LteRlc", level);
+ // LogComponentEnable ("LteRlcUm", level);
+ // LogComponentEnable ("LteRlcAm", level);
+
+ SeedManager::SetSeed (m_seed);
+
+ Ptr<LteSimpleHelper> lteSimpleHelper = CreateObject<LteSimpleHelper> ();
+ // lteSimpleHelper->EnableLogComponents ();
+ // lteSimpleHelper->EnableTraces ();
+
+ lteSimpleHelper->SetAttribute ("RlcEntity", StringValue ("RlcAm"));
+
+ // eNB and UE nodes
+ NodeContainer ueNodes;
+ NodeContainer enbNodes;
+ enbNodes.Create (numberOfNodes);
+ ueNodes.Create (numberOfNodes);
+
+ // Install LTE Devices to the nodes
+ NetDeviceContainer enbLteDevs = lteSimpleHelper->InstallEnbDevice (enbNodes);
+ NetDeviceContainer ueLteDevs = lteSimpleHelper->InstallUeDevice (ueNodes);
+
+ // Note: Just one eNB and UE is supported. Everything is done in InstallEnbDevice and InstallUeDevice
+
+ // Attach one UE per eNodeB
+ // for (uint16_t i = 0; i < numberOfNodes; i++)
+ // {
+ // lteSimpleHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(i));
+ // }
+
+ // lteSimpleHelper->ActivateEpsBearer (ueLteDevs, EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), EpcTft::Default ());
+
+
+ // Error models: downlink and uplink
+ Ptr<RateErrorModel> dlEm = CreateObjectWithAttributes<RateErrorModel> ("RanVar", RandomVariableValue (UniformVariable (0.0, 1.0)));
+ dlEm->SetAttribute ("ErrorRate", DoubleValue (m_losses));
+ dlEm->SetAttribute ("ErrorUnit", StringValue ("EU_PKT"));
+
+// Ptr<RateErrorModel> ueEm = CreateObjectWithAttributes<RateErrorModel> ("RanVar", RandomVariableValue (UniformVariable (0.0, 1.0)));
+// ueEm->SetAttribute ("ErrorRate", DoubleValue (m_losses));
+// ueEm->SetAttribute ("ErrorUnit", StringValue ("EU_PKT"));
+
+ // The below hooks will cause drops and receptions to be counted
+ ueLteDevs.Get (0)->SetAttribute ("ReceiveErrorModel", PointerValue (dlEm));
+ ueLteDevs.Get (0)->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&LteRlcAmE2eTestCase::DlDropEvent, this));
+// enbLteDevs.Get (0)->SetAttribute ("ReceiveErrorModel", PointerValue (enbEm));
+// enbLteDevs.Get (0)->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&LteRlcAmE2eTestCase::EnbDropEvent, this));
+
+ // Sending packets from RRC layer
+ lteSimpleHelper->m_enbRrc->SetArrivalTime (Seconds (0.010));
+ lteSimpleHelper->m_enbRrc->SetPduSize (100);
+
+ // MAC sends transmission opportunities (TxOpp)
+ lteSimpleHelper->m_enbMac->SetTxOppSize (150);
+ lteSimpleHelper->m_enbMac->SetTxOppTime (Seconds (0.005));
+ lteSimpleHelper->m_enbMac->SetTxOpportunityMode (LteTestMac::RANDOM_MODE);
+
+ // MAC sends transmission opportunities (TxOpp)
+ lteSimpleHelper->m_ueMac->SetTxOppSize (140);
+ lteSimpleHelper->m_ueMac->SetTxOppTime (Seconds (0.015));
+ lteSimpleHelper->m_ueMac->SetTxOpportunityMode (LteTestMac::RANDOM_MODE);
+
+ // Start/Stop pseudo-application at RRC layer
+ Simulator::Schedule (Seconds (0.100), &LteTestRrc::Start, lteSimpleHelper->m_enbRrc);
+ Simulator::Schedule (Seconds (1.100), &LteTestRrc::Stop, lteSimpleHelper->m_enbRrc);
+
+
+ Simulator::Stop (Seconds (15.000));
+ Simulator::Run ();
+
+ uint32_t txEnbRrcPdus = lteSimpleHelper->m_enbRrc->GetTxPdus ();
+ uint32_t rxUeRrcPdus = lteSimpleHelper->m_ueRrc->GetRxPdus ();
+
+ // NS_LOG_INFO ("Seed = " << m_seed);
+ // NS_LOG_INFO ("Losses (%) = " << uint32_t (m_losses * 100));
+
+ // NS_LOG_INFO ("dl dev drops = " << m_dlDrops);
+ // NS_LOG_INFO ("ul dev drops = " << m_ulDrops);
+
+ // NS_LOG_INFO ("eNB tx RRC count = " << txEnbRrcPdus);
+ // NS_LOG_INFO ("eNB rx RRC count = " << rxEnbRrcPdus);
+ // NS_LOG_INFO ("UE tx RRC count = " << txUeRrcPdus);
+ // NS_LOG_INFO ("UE rx RRC count = " << rxUeRrcPdus);
+
+ NS_LOG_INFO (m_seed << "\t" << m_losses << "\t" << txEnbRrcPdus << "\t" << rxUeRrcPdus << "\t" << m_dlDrops);
+
+ NS_TEST_ASSERT_MSG_EQ (txEnbRrcPdus, rxUeRrcPdus,
+ "TX PDUs (" << txEnbRrcPdus << ") != RX PDUs (" << rxUeRrcPdus << ")");
+
+ Simulator::Destroy ();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-rlc-am-e2e.h Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#ifndef LTE_TEST_RLC_AM_E2E_H
+#define LTE_TEST_RLC_AM_E2E_H
+
+#include "ns3/test.h"
+
+
+using namespace ns3;
+
+
+/**
+ * Test x.x.x RLC AM: End-to-end flow
+ */
+class LteRlcAmE2eTestSuite : public TestSuite
+{
+public:
+ LteRlcAmE2eTestSuite ();
+};
+
+
+class LteRlcAmE2eTestCase : public TestCase
+{
+ public:
+ LteRlcAmE2eTestCase (std::string name, uint32_t seed, double losses);
+ LteRlcAmE2eTestCase ();
+ virtual ~LteRlcAmE2eTestCase ();
+
+ private:
+ virtual void DoRun (void);
+
+ void DlDropEvent (Ptr<const Packet> p);
+ void UlDropEvent (Ptr<const Packet> p);
+
+ uint32_t m_dlDrops;
+ uint32_t m_ulDrops;
+
+ uint32_t m_seed;
+ double m_losses;
+};
+
+
+#endif // LTE_TEST_RLC_AM_E2E_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-rlc-um-e2e.cc Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/pointer.h"
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/lte-simple-helper.h"
+#include "ns3/error-model.h"
+#include "ns3/radio-bearer-stats-calculator.h"
+
+#include "ns3/lte-rlc-header.h"
+#include "ns3/lte-rlc-um.h"
+
+#include "ns3/lte-test-entities.h"
+#include "ns3/lte-test-rlc-um-e2e.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("LteRlcUmE2eTest");
+
+using namespace ns3;
+
+
+/**
+ * Test x.x.x RLC UM: End-to-end flow
+ */
+
+/**
+ * TestSuite
+ */
+
+LteRlcUmE2eTestSuite::LteRlcUmE2eTestSuite ()
+ : TestSuite ("lte-rlc-um-e2e", SYSTEM)
+{
+ // NS_LOG_INFO ("Creating LteRlcUmE2eTestSuite");
+
+ double losses[] = {0.0, 0.10, 0.25, 0.50, 0.75, 0.90, 1.00};
+ uint32_t seeds[] = {1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 10101};
+
+ for ( uint32_t l = 0 ; l < (sizeof (losses) / sizeof (double)) ; l++ )
+ {
+ for ( uint32_t s = 0 ; s < (sizeof (seeds) / sizeof (uint32_t)) ; s++ )
+ {
+ std::ostringstream name;
+ name << " Losses = " << losses[l] << "%. Seed = " << seeds[s];
+ AddTestCase (new LteRlcUmE2eTestCase (name.str (), seeds[s], losses[l]));
+ }
+ }
+}
+
+static LteRlcUmE2eTestSuite lteRlcUmE2eTestSuite;
+
+
+/**
+ * TestCase
+ */
+
+LteRlcUmE2eTestCase::LteRlcUmE2eTestCase (std::string name, uint32_t seed, double losses)
+ : TestCase (name)
+{
+ // NS_LOG_UNCOND ("Creating LteRlcUmTestingTestCase: " + name);
+
+ m_seed = seed;
+ m_losses = losses;
+
+ m_dlDrops = 0;
+ m_ulDrops = 0;
+}
+
+LteRlcUmE2eTestCase::~LteRlcUmE2eTestCase ()
+{
+}
+
+
+void
+LteRlcUmE2eTestCase::DlDropEvent (Ptr<const Packet> p)
+{
+ // NS_LOG_FUNCTION (this);
+ m_dlDrops++;
+}
+
+void
+LteRlcUmE2eTestCase::UlDropEvent (Ptr<const Packet> p)
+{
+ // NS_LOG_FUNCTION (this);
+ m_ulDrops++;
+}
+
+void
+LteRlcUmE2eTestCase::DoRun (void)
+{
+ uint16_t numberOfNodes = 1;
+
+ LogLevel level = (LogLevel) (LOG_LEVEL_ALL | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_PREFIX_FUNC);
+ LogComponentEnable ("LteRlcUmE2eTest", level);
+ // LogComponentEnable ("ErrorModel", level);
+ // LogComponentEnable ("LteSimpleHelper", level);
+ // LogComponentEnable ("LteSimpleNetDevice", level);
+ // LogComponentEnable ("SimpleNetDevice", level);
+ // LogComponentEnable ("SimpleChannel", level);
+ // LogComponentEnable ("LteTestEntities", level);
+ // LogComponentEnable ("LtePdcp", level);
+ // LogComponentEnable ("LteRlc", level);
+ // LogComponentEnable ("LteRlcUm", level);
+ // LogComponentEnable ("LteRlcAm", level);
+
+ SeedManager::SetSeed (m_seed);
+
+ Ptr<LteSimpleHelper> lteSimpleHelper = CreateObject<LteSimpleHelper> ();
+ // lteSimpleHelper->EnableLogComponents ();
+ // lteSimpleHelper->EnableTraces ();
+
+ lteSimpleHelper->SetAttribute ("RlcEntity", StringValue ("RlcUm"));
+
+ // eNB and UE nodes
+ NodeContainer ueNodes;
+ NodeContainer enbNodes;
+ enbNodes.Create (numberOfNodes);
+ ueNodes.Create (numberOfNodes);
+
+ // Install LTE Devices to the nodes
+ NetDeviceContainer enbLteDevs = lteSimpleHelper->InstallEnbDevice (enbNodes);
+ NetDeviceContainer ueLteDevs = lteSimpleHelper->InstallUeDevice (ueNodes);
+
+ // Note: Just one eNB and UE are supported. Everything is done in InstallEnbDevice and InstallUeDevice
+
+ // Attach one UE per eNodeB
+ // for (uint16_t i = 0; i < numberOfNodes; i++)
+ // {
+ // lteSimpleHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(i));
+ // }
+
+ // lteSimpleHelper->ActivateEpsBearer (ueLteDevs, EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT), EpcTft::Default ());
+
+ // Error models: downlink and uplink
+ Ptr<RateErrorModel> dlEm = CreateObjectWithAttributes<RateErrorModel> ("RanVar", RandomVariableValue (UniformVariable (0.0, 1.0)));
+ dlEm->SetAttribute ("ErrorRate", DoubleValue (m_losses));
+ dlEm->SetAttribute ("ErrorUnit", StringValue ("EU_PKT"));
+
+ Ptr<RateErrorModel> ulEm = CreateObjectWithAttributes<RateErrorModel> ("RanVar", RandomVariableValue (UniformVariable (0.0, 1.0)));
+ ulEm->SetAttribute ("ErrorRate", DoubleValue (m_losses));
+ ulEm->SetAttribute ("ErrorUnit", StringValue ("EU_PKT"));
+
+ // The below hooks will cause drops to be counted at simple phy layer
+ ueLteDevs.Get (0)->SetAttribute ("ReceiveErrorModel", PointerValue (dlEm));
+ ueLteDevs.Get (0)->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&LteRlcUmE2eTestCase::DlDropEvent, this));
+ enbLteDevs.Get (0)->SetAttribute ("ReceiveErrorModel", PointerValue (ulEm));
+ enbLteDevs.Get (0)->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&LteRlcUmE2eTestCase::UlDropEvent, this));
+
+ // Sending packets from eNB RRC layer (eNB -> UE)
+ lteSimpleHelper->m_enbRrc->SetArrivalTime (Seconds (0.010));
+ lteSimpleHelper->m_enbRrc->SetPduSize (100);
+
+ // MAC sends transmission opportunities (TxOpp)
+ lteSimpleHelper->m_enbMac->SetTxOppSize (150);
+ lteSimpleHelper->m_enbMac->SetTxOppTime (Seconds (0.005));
+ lteSimpleHelper->m_enbMac->SetTxOpportunityMode (LteTestMac::RANDOM_MODE);
+
+ // Sending packets from UE RRC layer (UE -> eNB)
+ lteSimpleHelper->m_ueRrc->SetArrivalTime (Seconds (0.010));
+ lteSimpleHelper->m_ueRrc->SetPduSize (100);
+
+ // MAC sends transmission opportunities (TxOpp)
+ lteSimpleHelper->m_ueMac->SetTxOppSize (150);
+ lteSimpleHelper->m_ueMac->SetTxOppTime (Seconds (0.005));
+ lteSimpleHelper->m_ueMac->SetTxOpportunityMode (LteTestMac::RANDOM_MODE);
+
+ // Start/Stop pseudo-application at eNB RRC
+ Simulator::Schedule (Seconds (0.100), &LteTestRrc::Start, lteSimpleHelper->m_enbRrc);
+ Simulator::Schedule (Seconds (10.100), &LteTestRrc::Stop, lteSimpleHelper->m_enbRrc);
+
+ // Start/Stop pseudo-application at UE RRC
+ Simulator::Schedule (Seconds (20.100), &LteTestRrc::Start, lteSimpleHelper->m_ueRrc);
+ Simulator::Schedule (Seconds (30.100), &LteTestRrc::Stop, lteSimpleHelper->m_ueRrc);
+
+
+ Simulator::Stop (Seconds (31.000));
+ Simulator::Run ();
+
+ uint32_t txEnbRrcPdus = lteSimpleHelper->m_enbRrc->GetTxPdus ();
+ uint32_t rxUeRrcPdus = lteSimpleHelper->m_ueRrc->GetRxPdus ();
+
+ uint32_t txUeRrcPdus = lteSimpleHelper->m_ueRrc->GetTxPdus ();
+ uint32_t rxEnbRrcPdus = lteSimpleHelper->m_enbRrc->GetRxPdus ();
+
+ // NS_LOG_INFO ("Seed = " << m_seed);
+ // NS_LOG_INFO ("Losses (%) = " << uint32_t (m_losses * 100));
+
+ // NS_LOG_INFO ("dl dev drops = " << m_dlDrops);
+ // NS_LOG_INFO ("ul dev drops = " << m_ulDrops);
+
+ // NS_LOG_INFO ("eNB tx RRC count = " << txEnbRrcPdus);
+ // NS_LOG_INFO ("eNB rx RRC count = " << rxEnbRrcPdus);
+ // NS_LOG_INFO ("UE tx RRC count = " << txUeRrcPdus);
+ // NS_LOG_INFO ("UE rx RRC count = " << rxUeRrcPdus);
+
+ NS_LOG_INFO (m_seed << "\t" << m_losses << "\t" << txEnbRrcPdus << "\t" << rxUeRrcPdus << "\t" << m_dlDrops);
+ NS_LOG_INFO (m_seed << "\t" << m_losses << "\t" << txUeRrcPdus << "\t" << rxEnbRrcPdus << "\t" << m_ulDrops);
+
+ NS_TEST_ASSERT_MSG_EQ (txEnbRrcPdus, rxUeRrcPdus + m_dlDrops,
+ "Downlink: TX PDUs (" << txEnbRrcPdus << ") != RX PDUs (" << rxUeRrcPdus << ") + DROPS (" << m_dlDrops << ")");
+ NS_TEST_ASSERT_MSG_EQ (txUeRrcPdus, rxEnbRrcPdus + m_ulDrops,
+ "Uplink: TX PDUs (" << txUeRrcPdus << ") != RX PDUs (" << rxEnbRrcPdus << ") + DROPS (" << m_ulDrops << ")");
+
+ Simulator::Destroy ();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-rlc-um-e2e.h Wed Feb 08 17:14:58 2012 +0100
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (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: Manuel Requena <manuel.requena@cttc.es>
+ */
+
+#ifndef LTE_TEST_RLC_UM_E2E_H
+#define LTE_TEST_RLC_UM_E2E_H
+
+#include "ns3/test.h"
+
+
+using namespace ns3;
+
+
+/**
+ * Test x.x.x RLC UM: End-to-end flow
+ */
+class LteRlcUmE2eTestSuite : public TestSuite
+{
+public:
+ LteRlcUmE2eTestSuite ();
+};
+
+
+class LteRlcUmE2eTestCase : public TestCase
+{
+ public:
+ LteRlcUmE2eTestCase (std::string name, uint32_t seed, double losses);
+ LteRlcUmE2eTestCase ();
+ virtual ~LteRlcUmE2eTestCase ();
+
+ private:
+ virtual void DoRun (void);
+
+ void DlDropEvent (Ptr<const Packet> p);
+ void UlDropEvent (Ptr<const Packet> p);
+
+ uint32_t m_dlDrops;
+ uint32_t m_ulDrops;
+
+ uint32_t m_seed;
+ double m_losses;
+};
+
+
+#endif // LTE_TEST_RLC_UM_E2E_H
--- a/src/lte/wscript Wed Feb 08 13:42:00 2012 +0100
+++ b/src/lte/wscript Wed Feb 08 17:14:58 2012 +0100
@@ -79,8 +79,12 @@
'test/lte-test-spectrum-value-helper.cc',
'test/lte-test-pathloss-model.cc',
'test/lte-test-entities.cc',
+ 'test/lte-simple-helper.cc',
+ 'test/lte-simple-net-device.cc',
'test/lte-test-rlc-um-transmitter.cc',
'test/lte-test-rlc-am-transmitter.cc',
+ 'test/lte-test-rlc-um-e2e.cc',
+ 'test/lte-test-rlc-am-e2e.cc',
'test/epc-test-gtpu.cc',
'test/test-epc-tft-classifier.cc',
'test/epc-test-s1u-downlink.cc',
@@ -162,8 +166,12 @@
'test/lte-test-pathloss-model.h',
'test/epc-test-gtpu.h',
'test/lte-test-entities.h',
+ 'test/lte-simple-net-device.h',
+ 'test/lte-simple-helper.h',
'test/lte-test-rlc-um-transmitter.h',
'test/lte-test-rlc-am-transmitter.h',
+ 'test/lte-test-rlc-um-e2e.h',
+ 'test/lte-test-rlc-am-e2e.h',
'model/epc-tft.h',
'model/epc-tft-classifier.h',
'model/lte-mi-error-model.h'