From b8cace6bcf825e0c8ddeeb8ebb032b66b6a1adb8 Mon Sep 17 00:00:00 2001 From: Manuel Requena Date: Thu, 19 Jan 2012 15:41:21 +0100 Subject: [PATCH] Fix processing of the sequence number --- src/lte/model/lte-rlc-header.cc | 10 +- src/lte/model/lte-rlc-header.h | 7 +- src/lte/model/lte-rlc-sequence-number.cc | 34 ++++++ src/lte/model/lte-rlc-sequence-number.h | 144 +++++++++++++++++++++++ src/lte/model/lte-rlc-um.cc | 59 ++++++---- src/lte/model/lte-rlc-um.h | 16 +-- src/lte/wscript | 6 +- 7 files changed, 238 insertions(+), 38 deletions(-) create mode 100644 src/lte/model/lte-rlc-sequence-number.cc create mode 100644 src/lte/model/lte-rlc-sequence-number.h diff --git a/src/lte/model/lte-rlc-header.cc b/src/lte/model/lte-rlc-header.cc index d4c292500..d34729c5a 100644 --- a/src/lte/model/lte-rlc-header.cc +++ b/src/lte/model/lte-rlc-header.cc @@ -49,9 +49,9 @@ LteRlcHeader::SetFramingInfo (uint8_t framingInfo) } void -LteRlcHeader::SetSequenceNumber (uint16_t sequenceNumber) +LteRlcHeader::SetSequenceNumber (SequenceNumber10 sequenceNumber) { - m_sequenceNumber = sequenceNumber & 0x03FF; + m_sequenceNumber = sequenceNumber; } uint8_t @@ -60,7 +60,7 @@ LteRlcHeader::GetFramingInfo () const return m_framingInfo; } -uint16_t +SequenceNumber10 LteRlcHeader::GetSequenceNumber () const { return m_sequenceNumber; @@ -173,8 +173,8 @@ void LteRlcHeader::Serialize (Buffer::Iterator start) const i.WriteU8 ( ((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 ); it1++; while ( it1 != m_extensionBits.end () && diff --git a/src/lte/model/lte-rlc-header.h b/src/lte/model/lte-rlc-header.h index e10285035..273a7148e 100644 --- a/src/lte/model/lte-rlc-header.h +++ b/src/lte/model/lte-rlc-header.h @@ -22,6 +22,7 @@ #define LTE_RLC_HEADER_H #include "ns3/header.h" +#include "ns3/lte-rlc-sequence-number.h" #include @@ -48,10 +49,10 @@ public: ~LteRlcHeader (); void SetFramingInfo (uint8_t framingInfo); - void SetSequenceNumber (uint16_t sequenceNumber); + void SetSequenceNumber (SequenceNumber10 sequenceNumber); uint8_t GetFramingInfo () const; - uint16_t GetSequenceNumber () const; + SequenceNumber10 GetSequenceNumber () const; void PushExtensionBit (uint8_t extensionBit); void PushLengthIndicator (uint16_t lengthIndicator); @@ -85,7 +86,7 @@ public: private: uint16_t m_headerLength; uint8_t m_framingInfo; // 2 bits - uint16_t m_sequenceNumber; // 10 bits TODO Maybe should be SequenceNumber10 or similar + SequenceNumber10 m_sequenceNumber; std::list m_extensionBits; // Includes extensionBit of the fixed part std::list m_lengthIndicators; diff --git a/src/lte/model/lte-rlc-sequence-number.cc b/src/lte/model/lte-rlc-sequence-number.cc new file mode 100644 index 000000000..8d1620a6a --- /dev/null +++ b/src/lte/model/lte-rlc-sequence-number.cc @@ -0,0 +1,34 @@ +/* -*- 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/lte-rlc-sequence-number.h" + +namespace ns3 { + + +std::ostream & +operator<< (std::ostream& os, const SequenceNumber10 &val) +{ + os << val.m_value; + return os; +} + + +} // namespace ns3 diff --git a/src/lte/model/lte-rlc-sequence-number.h b/src/lte/model/lte-rlc-sequence-number.h new file mode 100644 index 000000000..f583603bd --- /dev/null +++ b/src/lte/model/lte-rlc-sequence-number.h @@ -0,0 +1,144 @@ +/* -*- 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_RLC_SEQUENCE_NUMBER_H +#define LTE_RLC_SEQUENCE_NUMBER_H + +#include +#include +#include + +// #include "ns3/lte-rlc.h" + +namespace ns3 { + + +class SequenceNumber10 +{ +public: + SequenceNumber10 () + : m_value (0), + m_modulusBase (0) + {} + + explicit SequenceNumber10 (uint16_t value) + : m_value (value % 1024), + m_modulusBase (0) + {} + + SequenceNumber10 (SequenceNumber10 const &value) + : m_value (value.m_value), + m_modulusBase (value.m_modulusBase) + {} + + SequenceNumber10& operator= (uint16_t value) + { + m_value = value % 1024; + m_modulusBase = 0; + return *this; + } + + + /** + * \brief Extracts the numeric value of the sequence number + * \returns the sequence number value + */ + uint16_t GetValue () const + { + return m_value; + } + + void SetModulusBase (SequenceNumber10 modulusBase) + { + m_modulusBase = modulusBase.m_value; + } + + void SetModulusBase (uint16_t modulusBase) + { + m_modulusBase = modulusBase; + } + + // postfix ++ + SequenceNumber10 operator++ (int) + { + SequenceNumber10 retval (m_value); + m_value = (m_value + 1) % 1024; + return retval; + } + + SequenceNumber10 operator + (uint16_t delta) const + { + SequenceNumber10 ret ((m_value + delta) % 1024); + ret.SetModulusBase (m_modulusBase); + return ret; + } + + SequenceNumber10 operator - (uint16_t delta) const + { + SequenceNumber10 ret ((m_value - delta) % 1024); + ret.SetModulusBase (m_modulusBase); + return ret; + } + + uint16_t operator - (const SequenceNumber10 &other) const + { + uint16_t diff = m_value - other.m_value; + return (diff); + } + + bool operator > (const SequenceNumber10 &other) const + { + SequenceNumber10 v1 ((m_value - m_modulusBase) % 1024); + SequenceNumber10 v2 ((other.m_value - other.m_modulusBase) % 1024); + return ( v1.GetValue () > v2.GetValue () ); + } + + bool operator == (const SequenceNumber10 &other) const + { + return (m_value == other.m_value); + } + + bool operator != (const SequenceNumber10 &other) const + { + return (m_value != other.m_value); + } + + bool operator <= (const SequenceNumber10 &other) const + { + return (!this->operator> (other)); + } + + bool operator < (const SequenceNumber10 &other) const + { + return !this->operator> (other) && m_value != other.m_value; + } + + + friend std::ostream & operator<< (std::ostream& os, const SequenceNumber10 &val); + +private: + uint16_t m_value; + uint16_t m_modulusBase; +}; + + +} // namespace ns3 + +#endif // LTE_RLC_SEQUENCE_NUMBER_H diff --git a/src/lte/model/lte-rlc-um.cc b/src/lte/model/lte-rlc-um.cc index b98015818..4cbccaa55 100644 --- a/src/lte/model/lte-rlc-um.cc +++ b/src/lte/model/lte-rlc-um.cc @@ -295,7 +295,7 @@ LteRlcUm::DoNotifyTxOpportunity (uint32_t bytes) } // Build RLC header - rlcHeader.SetSequenceNumber ( (m_sequenceNumber++) % 1024 ); // TODO See SetIdentification in ipv4 header + rlcHeader.SetSequenceNumber (m_sequenceNumber++); // Build RLC PDU with DataField and Header std::vector< Ptr >::iterator it; @@ -390,11 +390,11 @@ LteRlcUm::DoReceivePdu (Ptr p) LteRlcHeader rlcHeader; p->PeekHeader (rlcHeader); NS_LOG_LOGIC ("RLC header: " << rlcHeader); - uint16_t seqNumber = rlcHeader.GetSequenceNumber (); + SequenceNumber10 seqNumber = rlcHeader.GetSequenceNumber (); // 5.1.2.2.1 General // The receiving UM RLC entity shall maintain a reordering window according to state variable VR(UH) as follows: - // - a SN falls within the reordering window if (VR(UH) UM_Window_Size) <= SN < VR(UH); + // - a SN falls within the reordering window if (VR(UH) - UM_Window_Size) <= SN < VR(UH); // - a SN falls outside of the reordering window otherwise. // When receiving an UMD PDU from lower layer, the receiving UM RLC entity shall: // - either discard the received UMD PDU or place it in the reception buffer (see sub clause 5.1.2.2.2); @@ -416,7 +416,11 @@ LteRlcUm::DoReceivePdu (Ptr p) NS_LOG_LOGIC ("VR(UH) = " << m_vrUh); NS_LOG_LOGIC ("SN = " << seqNumber); - if ( ( (m_vrUr < seqNumber) && (seqNumber < m_vrUh) && (m_rxBuffer.count (seqNumber) > 0) ) || + m_vrUr.SetModulusBase (m_vrUh - m_windowSize); + m_vrUh.SetModulusBase (m_vrUh - m_windowSize); + seqNumber.SetModulusBase (m_vrUh - m_windowSize); + + if ( ( (m_vrUr < seqNumber) && (seqNumber < m_vrUh) && (m_rxBuffer.count (seqNumber.GetValue ()) > 0) ) || ( ((m_vrUh - m_windowSize) <= seqNumber) && (seqNumber < m_vrUr) ) ) { @@ -427,7 +431,7 @@ LteRlcUm::DoReceivePdu (Ptr p) else { NS_LOG_LOGIC ("Place UMD PDU in the reception buffer"); - m_rxBuffer[seqNumber] = p; + m_rxBuffer[seqNumber.GetValue ()] = p; } @@ -444,7 +448,7 @@ LteRlcUm::DoReceivePdu (Ptr p) if ( ! IsInsideReorderingWindow (seqNumber)) { - NS_LOG_LOGIC ("SN outside the reordering window"); + NS_LOG_LOGIC ("SN is outside the reordering window"); m_vrUh = seqNumber + 1; NS_LOG_LOGIC ("New VR(UH) = " << m_vrUh); @@ -454,7 +458,7 @@ LteRlcUm::DoReceivePdu (Ptr p) if ( ! IsInsideReorderingWindow (m_vrUr) ) { m_vrUr = m_vrUh - m_windowSize; - NS_LOG_LOGIC ("VR(UR) outside the reordering window"); + NS_LOG_LOGIC ("VR(UR) is outside the reordering window"); NS_LOG_LOGIC ("New VR(UR) = " << m_vrUr); } } @@ -465,14 +469,14 @@ LteRlcUm::DoReceivePdu (Ptr p) // so and deliver the reassembled RLC SDUs to upper layer in ascending order of the RLC SN if not delivered // before; - if ( m_rxBuffer.count (m_vrUr) > 0 ) + if ( m_rxBuffer.count (m_vrUr.GetValue ()) > 0 ) { NS_LOG_LOGIC ("Reception buffer contains SN = " << m_vrUr); std::map >::iterator it; uint16_t newVrUr; - it = m_rxBuffer.find (m_vrUr); + it = m_rxBuffer.find (m_vrUr.GetValue ()); newVrUr = (it->first) + 1; while ( m_rxBuffer.count (newVrUr) > 0 ) { @@ -532,14 +536,23 @@ LteRlcUm::Start () bool -LteRlcUm::IsInsideReorderingWindow (uint16_t seqNumber) +LteRlcUm::IsInsideReorderingWindow (SequenceNumber10 seqNumber) { + NS_LOG_FUNCTION (this << seqNumber); + NS_LOG_LOGIC ("Reordering Window: " << + m_vrUh << " - " << m_windowSize << " <= " << seqNumber << " < " << m_vrUh); + + m_vrUh.SetModulusBase (m_vrUh - m_windowSize); + seqNumber.SetModulusBase (m_vrUh - m_windowSize); + if ( ((m_vrUh - m_windowSize) <= seqNumber) && (seqNumber < m_vrUh)) { + NS_LOG_LOGIC (seqNumber << "is INSIDE the reordering window"); return true; } else { + NS_LOG_LOGIC (seqNumber << "is OUTSIDE the reordering window"); return false; } } @@ -551,7 +564,7 @@ LteRlcUm::ReassembleAndDeliver (Ptr packet) LteRlcHeader rlcHeader; packet->RemoveHeader (rlcHeader); uint8_t framingInfo = rlcHeader.GetFramingInfo (); - uint16_t currSeqNumber = rlcHeader.GetSequenceNumber (); // TODO Needed if losses + SequenceNumber10 currSeqNumber = rlcHeader.GetSequenceNumber (); bool expectedSnLost; if ( currSeqNumber != m_expectedSeqNumber ) @@ -972,14 +985,16 @@ LteRlcUm::ReassembleOutsideWindow (void) std::map >::iterator it; it = m_rxBuffer.begin (); - while ( (it != m_rxBuffer.end ()) && ! IsInsideReorderingWindow (it->first) ) + while ( (it != m_rxBuffer.end ()) && ! IsInsideReorderingWindow (SequenceNumber10 (it->first)) ) { NS_LOG_LOGIC ("SN = " << it->first); // Reassemble RLC SDUs and deliver the PDCP PDU to upper layer ReassembleAndDeliver (it->second); - m_rxBuffer.erase (it); - it++; + + std::map >::iterator it_tmp = it; + ++it; + m_rxBuffer.erase (it_tmp); } if (it != m_rxBuffer.end ()) @@ -989,26 +1004,28 @@ LteRlcUm::ReassembleOutsideWindow (void) } void -LteRlcUm::ReassembleSnLessThan (uint16_t seqNumber) +LteRlcUm::ReassembleSnLessThan (SequenceNumber10 seqNumber) { NS_LOG_LOGIC ("Reassemble SN < updated VR(UR)" ); std::map >::iterator it; it = m_rxBuffer.begin (); - while ( (it != m_rxBuffer.end ()) && (it->first < seqNumber) ) + while ( (it != m_rxBuffer.end ()) && (it->first < seqNumber.GetValue ()) ) { NS_LOG_LOGIC ("SN = " << it->first); // Reassemble RLC SDUs and deliver the PDCP PDU to upper layer ReassembleAndDeliver (it->second); - m_rxBuffer.erase (it); - it++; + + std::map >::iterator it_tmp = it; + ++it; + m_rxBuffer.erase (it_tmp); } if (it != m_rxBuffer.end ()) { - NS_LOG_LOGIC ("(SN = " << it->first << ") >= " << m_vrUr); + NS_LOG_LOGIC ("(SN = " << it->first << ") >= " << m_vrUr.GetValue ()); } } @@ -1057,9 +1074,9 @@ LteRlcUm::ExpireReorderingTimer (void) // - set VR(UX) to VR(UH). std::map >::iterator it; - uint16_t newVrUr = m_vrUx; + SequenceNumber10 newVrUr = m_vrUx; - while ( (it = m_rxBuffer.find (newVrUr)) != m_rxBuffer.end () ) + while ( (it = m_rxBuffer.find (newVrUr.GetValue ())) != m_rxBuffer.end () ) { newVrUr++; } diff --git a/src/lte/model/lte-rlc-um.h b/src/lte/model/lte-rlc-um.h index 59ee78c14..537939e7d 100644 --- a/src/lte/model/lte-rlc-um.h +++ b/src/lte/model/lte-rlc-um.h @@ -21,6 +21,8 @@ #ifndef LTE_RLC_UM_H #define LTE_RLC_UM_H +#include "ns3/lte-rlc-sequence-number.h" + #include "ns3/lte-rlc.h" #include @@ -55,10 +57,10 @@ private: void ExpireReorderingTimer (void); void ExpireRbsTimer (void); - bool IsInsideReorderingWindow (uint16_t seqNumber); + bool IsInsideReorderingWindow (SequenceNumber10 seqNumber); void ReassembleOutsideWindow (void); - void ReassembleSnLessThan (uint16_t seqNumber); + void ReassembleSnLessThan (SequenceNumber10 seqNumber); void ReassembleAndDeliver (Ptr packet); @@ -75,11 +77,11 @@ private: /** * State variables. See section 7.1 in TS 36.322 */ - uint16_t m_sequenceNumber; // VT(US) + SequenceNumber10 m_sequenceNumber; // VT(US) - uint16_t m_vrUr; // VR(UR) - uint16_t m_vrUx; // VR(UX) - uint16_t m_vrUh; // VR(UH) + SequenceNumber10 m_vrUr; // VR(UR) + SequenceNumber10 m_vrUx; // VR(UX) + SequenceNumber10 m_vrUh; // VR(UH) /** * Constants. See section 7.2 in TS 36.322 @@ -104,7 +106,7 @@ private: /** * Expected Sequence Number */ - uint16_t m_expectedSeqNumber; + SequenceNumber10 m_expectedSeqNumber; }; diff --git a/src/lte/wscript b/src/lte/wscript index 812de27c6..632eb6afe 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -16,6 +16,7 @@ def build(bld): 'model/lte-ue-rrc.cc', 'model/lte-rlc-sap.cc', 'model/lte-rlc.cc', + 'model/lte-rlc-sequence-number.cc', 'model/lte-rlc-header.cc', 'model/lte-rlc-am-header.cc', 'model/lte-rlc-um.cc', @@ -108,6 +109,7 @@ def build(bld): 'model/lte-rlc-sap.h', 'model/lte-rlc.h', 'model/lte-rlc-header.h', + 'model/lte-rlc-sequence-number.h', 'model/lte-rlc-am-header.h', 'model/lte-rlc-um.h', 'model/lte-rlc-am.h', @@ -129,8 +131,8 @@ def build(bld): 'helper/epc-helper.h', 'helper/mac-stats-calculator.h', 'helper/radio-bearer-stats-calculator.h', - 'helper/radio-environment-map-helper.h', - 'model/rem-spectrum-phy.h', + 'helper/radio-environment-map-helper.h', + 'model/rem-spectrum-phy.h', 'model/ff-mac-common.h', 'model/ff-mac-csched-sap.h', 'model/ff-mac-sched-sap.h',