Fix processing of the sequence number
This commit is contained in:
@@ -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 () &&
|
||||
|
||||
@@ -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;
|
||||
|
||||
34
src/lte/model/lte-rlc-sequence-number.cc
Normal file
34
src/lte/model/lte-rlc-sequence-number.cc
Normal 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
|
||||
144
src/lte/model/lte-rlc-sequence-number.h
Normal file
144
src/lte/model/lte-rlc-sequence-number.h
Normal 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
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user