Fix processing of the sequence number
authorManuel Requena <manuel.requena@cttc.es>
Thu, 19 Jan 2012 15:41:21 +0100
changeset 8572 ada66b065cc2
parent 8571 1cb2ad403831
child 8573 45bb3b0dacbd
Fix processing of the sequence number
src/lte/model/lte-rlc-header.cc
src/lte/model/lte-rlc-header.h
src/lte/model/lte-rlc-sequence-number.cc
src/lte/model/lte-rlc-sequence-number.h
src/lte/model/lte-rlc-um.cc
src/lte/model/lte-rlc-um.h
src/lte/wscript
--- a/src/lte/model/lte-rlc-header.cc	Thu Jan 19 13:07:47 2012 +0100
+++ b/src/lte/model/lte-rlc-header.cc	Thu Jan 19 15:41:21 2012 +0100
@@ -49,9 +49,9 @@
 }
 
 void
-LteRlcHeader::SetSequenceNumber (uint16_t sequenceNumber)
+LteRlcHeader::SetSequenceNumber (SequenceNumber10 sequenceNumber)
 {
-  m_sequenceNumber = sequenceNumber & 0x03FF;
+  m_sequenceNumber = sequenceNumber;
 }
 
 uint8_t
@@ -60,7 +60,7 @@
   return m_framingInfo;
 }
 
-uint16_t
+SequenceNumber10
 LteRlcHeader::GetSequenceNumber () const
 {
   return m_sequenceNumber;
@@ -173,8 +173,8 @@
 
   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 () &&
--- a/src/lte/model/lte-rlc-header.h	Thu Jan 19 13:07:47 2012 +0100
+++ b/src/lte/model/lte-rlc-header.h	Thu Jan 19 15:41:21 2012 +0100
@@ -22,6 +22,7 @@
 #define LTE_RLC_HEADER_H
 
 #include "ns3/header.h"
+#include "ns3/lte-rlc-sequence-number.h"
 
 #include <list>
 
@@ -48,10 +49,10 @@
   ~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 @@
 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 <uint8_t> m_extensionBits; // Includes extensionBit of the fixed part
   std::list <uint16_t> m_lengthIndicators;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-rlc-sequence-number.cc	Thu Jan 19 15:41:21 2012 +0100
@@ -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 <manuel.requena@cttc.es>
+ */
+
+#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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-rlc-sequence-number.h	Thu Jan 19 15:41:21 2012 +0100
@@ -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 <manuel.requena@cttc.es>
+ */
+
+#ifndef LTE_RLC_SEQUENCE_NUMBER_H
+#define LTE_RLC_SEQUENCE_NUMBER_H
+
+#include <limits>
+#include <iostream>
+#include <stdint.h>
+
+// #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
--- a/src/lte/model/lte-rlc-um.cc	Thu Jan 19 13:07:47 2012 +0100
+++ b/src/lte/model/lte-rlc-um.cc	Thu Jan 19 15:41:21 2012 +0100
@@ -295,7 +295,7 @@
     }
 
   // 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<Packet> >::iterator it;
@@ -390,11 +390,11 @@
   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 @@
   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 @@
   else
     {
       NS_LOG_LOGIC ("Place UMD PDU in the reception buffer");
-      m_rxBuffer[seqNumber] = p;
+      m_rxBuffer[seqNumber.GetValue ()] = p;
     }
 
 
@@ -444,7 +448,7 @@
 
   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 @@
       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 @@
   //      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 <uint16_t, Ptr<Packet> >::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 @@
 
 
 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 @@
   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 @@
   std::map <uint16_t, Ptr<Packet> >::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 <uint16_t, Ptr<Packet> >::iterator it_tmp = it;
+      ++it;
+      m_rxBuffer.erase (it_tmp);
     }
 
   if (it != m_rxBuffer.end ())
@@ -989,26 +1004,28 @@
 }
 
 void
-LteRlcUm::ReassembleSnLessThan (uint16_t seqNumber)
+LteRlcUm::ReassembleSnLessThan (SequenceNumber10 seqNumber)
 {
   NS_LOG_LOGIC ("Reassemble SN < updated VR(UR)" );
 
   std::map <uint16_t, Ptr<Packet> >::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 <uint16_t, Ptr<Packet> >::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 @@
   //    - set VR(UX) to VR(UH).
 
   std::map <uint16_t, Ptr<Packet> >::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++;
     }
--- a/src/lte/model/lte-rlc-um.h	Thu Jan 19 13:07:47 2012 +0100
+++ b/src/lte/model/lte-rlc-um.h	Thu Jan 19 15:41:21 2012 +0100
@@ -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 <map>
@@ -55,10 +57,10 @@
   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> packet);
 
@@ -75,11 +77,11 @@
   /**
    * 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 @@
   /**
    * Expected Sequence Number
    */
-  uint16_t m_expectedSeqNumber;
+  SequenceNumber10 m_expectedSeqNumber;
 
 };
 
--- a/src/lte/wscript	Thu Jan 19 13:07:47 2012 +0100
+++ b/src/lte/wscript	Thu Jan 19 15:41:21 2012 +0100
@@ -16,6 +16,7 @@
         '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 @@
         '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 @@
         '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',