2025-12-01 15:56:02 +01:00
# include "frer-vector-recovery-function.h"
# include "ns3/log.h"
# include "ns3/simulator.h"
# include "ns3/uinteger.h"
namespace ns3
{
NS_LOG_COMPONENT_DEFINE ( " VectorRecoveryFunction " ) ;
NS_OBJECT_ENSURE_REGISTERED ( VectorRecoveryFunction ) ;
TypeId
VectorRecoveryFunction : : GetTypeId ( )
{
static TypeId tid =
TypeId ( " ns3::VectorRecoveryFunction " )
. SetParent < BaseRecoveryFunction > ( )
. SetGroupName ( " tsn " )
. AddConstructor < VectorRecoveryFunction > ( )
. AddAttribute ( " HistoryLenght " ,
" Lenght of the history for the vector recovery algorithm " ,
UintegerValue ( 2 ) ,
MakeUintegerAccessor ( & VectorRecoveryFunction : : m_frerSeqRcvyHistoryLenght ) ,
MakeUintegerChecker < uint > ( ) )
. AddAttribute ( " MaxHistoryLenght " ,
" Max Lenght of the history for the vector recovery algorithm " ,
UintegerValue ( 65535 ) ,
MakeUintegerAccessor ( & VectorRecoveryFunction : : m_maxFrerSeqRcvyHistoryLenght ) ,
MakeUintegerChecker < uint16_t > ( ) ) ;
return tid ;
}
VectorRecoveryFunction : : VectorRecoveryFunction ( )
{
NS_LOG_FUNCTION ( this ) ;
}
VectorRecoveryFunction : : ~ VectorRecoveryFunction ( )
{
NS_LOG_FUNCTION ( this ) ;
}
bool
VectorRecoveryFunction : : DoRecovery ( uint16_t seqNumber )
{
NS_LOG_FUNCTION ( this ) ;
NS_ASSERT_MSG ( m_frerSeqRcvyResetMSec < = m_frerMaxSeqRcvyResetMSec , " Trying to use a longer recovery reset timer than " < < m_frerMaxSeqRcvyResetMSec < < " . " ) ;
NS_ASSERT_MSG ( m_frerSeqRcvyHistoryLenght < = m_maxFrerSeqRcvyHistoryLenght , " Trying to use a longer HistoryLenght than " < < m_maxFrerSeqRcvyHistoryLenght < < " . " ) ;
// Compute signed difference modulo RecovSeqSpace
int delta = ( seqNumber - m_recovSeqNum ) % m_recovSeqSpace ;
if ( 0 ! = ( delta & ( m_recovSeqSpace / 2 ) ) )
{
delta = delta - m_recovSeqSpace ;
// Here, -(m_recovSeqSpace/2)<=delta<=((m_recovSeqSpace/2)-1)
}
// After reset, accept any packet
if ( m_takeAny )
{
m_takeAny = false ;
m_sequenceHistory . clear ( ) ; //Empty the vector in case of reset
m_sequenceHistory . insert ( m_sequenceHistory . begin ( ) , true ) ; //Add a "seen" bool
for ( int i = 0 ; i < m_frerSeqRcvyHistoryLenght - 1 ; i + + )
{
m_sequenceHistory . insert ( m_sequenceHistory . end ( ) , false ) ; //Fill the others bool
}
m_recovSeqNum = seqNumber ;
m_frerCpsSeqRcvyPassedPackets + = 1 ;
Simulator : : Cancel ( m_resetEvent ) ;
m_resetEvent = Simulator : : Schedule ( m_frerSeqRcvyResetMSec , & BaseRecoveryFunction : : resetRecoveryFunction , this ) ;
return true ;
}
2025-12-03 09:59:44 +01:00
else if ( delta > m_frerSeqRcvyHistoryLenght | | delta < = - m_frerSeqRcvyHistoryLenght )
2025-12-01 15:56:02 +01:00
{
// Packet is out-of-range. Count and discard it.
m_frerCpsSeqRcvyRoguePackets + = 1 ;
m_frerCpsSeqRcvyDiscardedPackets + = 1 ;
if ( m_frerSeqRcvyIndividualRecovery )
{
Simulator : : Cancel ( m_resetEvent ) ;
m_resetEvent = Simulator : : Schedule ( m_frerSeqRcvyResetMSec , & BaseRecoveryFunction : : resetRecoveryFunction , this ) ;
}
return false ;
}
else if ( delta < = 0 )
{
// Packet is old and in SequenceHistory; have we seen it before?
if ( not m_sequenceHistory [ - delta ] )
{
// Packet has not been seen. Take it.
m_sequenceHistory [ - delta ] = true ;
m_frerCpsSeqRcvyOutOfOrderPackets + = 1 ;
m_frerCpsSeqRcvyPassedPackets + = 1 ;
Simulator : : Cancel ( m_resetEvent ) ;
m_resetEvent = Simulator : : Schedule ( m_frerSeqRcvyResetMSec , & BaseRecoveryFunction : : resetRecoveryFunction , this ) ;
return true ;
}
else
{
// Packet has been seen. Drop it.
m_frerCpsSeqRcvyDiscardedPackets + = 1 ;
if ( m_frerSeqRcvyIndividualRecovery )
{
Simulator : : Cancel ( m_resetEvent ) ;
m_resetEvent = Simulator : : Schedule ( m_frerSeqRcvyResetMSec , & BaseRecoveryFunction : : resetRecoveryFunction , this ) ;
}
return false ;
}
}
else
{
// Packet is not too far ahead of the one we want.
// Packet is out-of-order unless it directly follows RecovSeqNum
if ( delta ! = 1 )
{
m_frerCpsSeqRcvyOutOfOrderPackets + = 1 ;
}
// Shift the history until bit 0 refers to sequence_number.
while ( 0 ! = ( delta = delta - 1 ) ) {
m_sequenceHistory . insert ( m_sequenceHistory . begin ( ) , false ) ;
}
m_sequenceHistory . insert ( m_sequenceHistory . begin ( ) , true ) ;
m_sequenceHistory . resize ( m_frerSeqRcvyHistoryLenght ) ;
m_recovSeqNum = seqNumber ;
m_frerCpsSeqRcvyPassedPackets + = 1 ;
Simulator : : Cancel ( m_resetEvent ) ;
m_resetEvent = Simulator : : Schedule ( m_frerSeqRcvyResetMSec , & BaseRecoveryFunction : : resetRecoveryFunction , this ) ;
return true ;
}
return false ;
}
}