Fix processing of the sequence number

This commit is contained in:
Manuel Requena
2012-01-19 15:41:21 +01:00
parent e1738e5c58
commit b8cace6bcf
7 changed files with 238 additions and 38 deletions

View File

@@ -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 () &&

View File

@@ -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 @@ 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 <uint8_t> m_extensionBits; // Includes extensionBit of the fixed part
std::list <uint16_t> m_lengthIndicators;

View File

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

View File

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

View File

@@ -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<Packet> >::iterator it;
@@ -390,11 +390,11 @@ LteRlcUm::DoReceivePdu (Ptr<Packet> 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<Packet> 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<Packet> 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<Packet> 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<Packet> 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<Packet> 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 <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 @@ 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> 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 <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 @@ LteRlcUm::ReassembleOutsideWindow (void)
}
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 @@ LteRlcUm::ExpireReorderingTimer (void)
// - 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++;
}

View File

@@ -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 @@ 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> 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;
};

View File

@@ -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',