# HG changeset patch # User Manuel Requena # Date 1328717698 -3600 # Node ID 859fa94888fc33d22f822c89967c713ea896a893 # Parent b86b82c7669392685fa6b2e236b2a4388ee4b0d6# Parent db24d2db55d43aad2cd646a8e9cb3dae12ec92cb Merge new tests of RLC entities diff -r db24d2db55d4 -r 859fa94888fc src/lte/model/lte-rlc-am-header.cc --- 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); diff -r db24d2db55d4 -r 859fa94888fc src/lte/model/lte-rlc-am-header.h --- 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 @@ -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 m_extensionBits1; // Includes E1 after ACK_SN std::list m_extensionBits2; diff -r db24d2db55d4 -r 859fa94888fc src/lte/model/lte-rlc-am.cc --- 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 = 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) { diff -r db24d2db55d4 -r 859fa94888fc src/lte/model/lte-rlc-am.h --- 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 @@ -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 > 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; }; diff -r db24d2db55d4 -r 859fa94888fc src/lte/model/lte-rlc-sequence-number.h --- 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; diff -r db24d2db55d4 -r 859fa94888fc src/lte/model/lte-rlc-um.cc --- 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 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); } } diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-simple-helper.cc --- /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 (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 (); + + Object::DoStart (); +} + +LteSimpleHelper::~LteSimpleHelper (void) +{ + NS_LOG_FUNCTION (this); +} + +TypeId LteSimpleHelper::GetTypeId (void) +{ + static TypeId + tid = + TypeId ("ns3::LteSimpleHelper") + .SetParent () + .AddConstructor () + .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 = *i; + Ptr 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 = *i; + Ptr device = InstallSingleUeDevice (node); + devices.Add (device); + } + return devices; +} + + +Ptr +LteSimpleHelper::InstallSingleEnbDevice (Ptr n) +{ + NS_LOG_FUNCTION (this); + + m_enbRrc = CreateObject (); + m_enbPdcp = CreateObject (); + + if (m_lteRlcEntityType == RLC_UM) + { + m_enbRlc = CreateObject (); + } + else // m_lteRlcEntityType == RLC_AM + { + m_enbRlc = CreateObject (); + } + + m_enbRlc->SetRnti (11); + m_enbRlc->SetLcId (12); + + Ptr enbDev = m_enbDeviceFactory.Create (); + enbDev->SetAddress (Mac48Address::Allocate ()); + enbDev->SetChannel (m_phyChannel); + + n->AddDevice (enbDev); + + m_enbMac = CreateObject (); + 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 +LteSimpleHelper::InstallSingleUeDevice (Ptr n) +{ + NS_LOG_FUNCTION (this); + + m_ueRrc = CreateObject (); + m_uePdcp = CreateObject (); + + if (m_lteRlcEntityType == RLC_UM) + { + m_ueRlc = CreateObject (); + } + else // m_lteRlcEntityType == RLC_AM + { + m_ueRlc = CreateObject (); + } + + m_ueRlc->SetRnti (21); + m_ueRlc->SetLcId (22); + + Ptr ueDev = m_ueDeviceFactory.Create (); + ueDev->SetAddress (Mac48Address::Allocate ()); + ueDev->SetChannel (m_phyChannel); + + n->AddDevice (ueDev); + + m_ueMac = CreateObject (); + 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 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 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 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 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 diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-simple-helper.h --- /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 (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 InstallSingleEnbDevice (Ptr n); + Ptr InstallSingleUeDevice (Ptr n); + + Ptr m_phyChannel; + +public: + + Ptr m_enbRrc; + Ptr m_ueRrc; + + Ptr m_enbMac; + Ptr m_ueMac; + +private: + + Ptr m_enbPdcp; + Ptr m_enbRlc; + + Ptr m_uePdcp; + Ptr 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 diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-simple-net-device.cc --- /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 + */ + +#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 () + .AddConstructor () + ; + + return tid; +} + + +LteSimpleNetDevice::LteSimpleNetDevice (void) +{ + NS_LOG_FUNCTION (this); +} + + +LteSimpleNetDevice::LteSimpleNetDevice (Ptr 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, const Address& dest, uint16_t protocolNumber) +{ + NS_LOG_FUNCTION (this << dest << protocolNumber); + return SimpleNetDevice::Send (packet, dest, protocolNumber); +} + + +} // namespace ns3 diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-simple-net-device.h --- /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 + */ + +#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); + + virtual ~LteSimpleNetDevice (void); + virtual void DoDispose (); + + + // inherited from NetDevice + virtual bool Send (Ptr packet, const Address& dest, uint16_t protocolNumber); + + +protected: + // inherited from Object + virtual void DoStart (void); + +}; + +} // namespace ns3 + + +#endif // LTE_SIMPLE_NET_DEVICE_H diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-test-entities.cc --- 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 (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 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 (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 ((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 ((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 (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 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 nd, Ptr p, uint16_t protocol, const Address& addr) +{ + NS_LOG_FUNCTION (this << addr << protocol << p->GetSize ()); + + m_rxPdus++; + m_rxBytes += p->GetSize (); + + Ptr packet = p->Copy (); + m_macSapUser->ReceivePdu (packet); + return true; } diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-test-entities.h --- 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 device); + + void SendTxOpportunity (Time, uint32_t); std::string GetDataReceived (void); + bool Receive (Ptr nd, Ptr 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 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; }; diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-test-rlc-am-e2e.cc --- /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 + */ + +#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 p) +{ + // NS_LOG_FUNCTION (this); + m_dlDrops++; +} + +void +LteRlcAmE2eTestCase::UlDropEvent (Ptr 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 = CreateObject (); + // 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 dlEm = CreateObjectWithAttributes ("RanVar", RandomVariableValue (UniformVariable (0.0, 1.0))); + dlEm->SetAttribute ("ErrorRate", DoubleValue (m_losses)); + dlEm->SetAttribute ("ErrorUnit", StringValue ("EU_PKT")); + +// Ptr ueEm = CreateObjectWithAttributes ("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 (); +} diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-test-rlc-am-e2e.h --- /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 + */ + +#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 p); + void UlDropEvent (Ptr p); + + uint32_t m_dlDrops; + uint32_t m_ulDrops; + + uint32_t m_seed; + double m_losses; +}; + + +#endif // LTE_TEST_RLC_AM_E2E_H diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-test-rlc-um-e2e.cc --- /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 + */ + +#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 p) +{ + // NS_LOG_FUNCTION (this); + m_dlDrops++; +} + +void +LteRlcUmE2eTestCase::UlDropEvent (Ptr 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 = CreateObject (); + // 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 dlEm = CreateObjectWithAttributes ("RanVar", RandomVariableValue (UniformVariable (0.0, 1.0))); + dlEm->SetAttribute ("ErrorRate", DoubleValue (m_losses)); + dlEm->SetAttribute ("ErrorUnit", StringValue ("EU_PKT")); + + Ptr ulEm = CreateObjectWithAttributes ("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 (); +} diff -r db24d2db55d4 -r 859fa94888fc src/lte/test/lte-test-rlc-um-e2e.h --- /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 + */ + +#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 p); + void UlDropEvent (Ptr p); + + uint32_t m_dlDrops; + uint32_t m_ulDrops; + + uint32_t m_seed; + double m_losses; +}; + + +#endif // LTE_TEST_RLC_UM_E2E_H diff -r db24d2db55d4 -r 859fa94888fc src/lte/wscript --- 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'