Update README and add contrib dir
This commit is contained in:
140
contrib/tsn/model/frer-vector-recovery-function.cc
Normal file
140
contrib/tsn/model/frer-vector-recovery-function.cc
Normal file
@@ -0,0 +1,140 @@
|
||||
#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;
|
||||
}
|
||||
else if (delta >= m_frerSeqRcvyHistoryLenght || delta <= -m_frerSeqRcvyHistoryLenght)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user