1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-12-02 17:51:06 +01:00
libtgvoip/controller/protocol/Ack.cpp

70 lines
1.6 KiB
C++
Raw Normal View History

2020-01-27 17:18:33 +01:00
#include "Ack.h"
#include "../PrivateDefines.h"
2020-01-27 19:53:32 +01:00
#include "../../tools/logging.h"
2020-01-27 17:18:33 +01:00
using namespace tgvoip;
using namespace std;
2020-01-27 19:53:32 +01:00
Ack::Ack() : recentIncomingSeqs(MAX_RECENT_PACKETS) {}
void Ack::ackLocal(uint32_t ackId, uint32_t mask)
2020-01-27 17:18:33 +01:00
{
peerAcks[0] = ackId;
for (unsigned int i = 1; i <= 32; i++)
{
peerAcks[i] = (mask >> (32 - i)) & 1 ? ackId - i : 0;
}
}
2020-01-27 19:53:32 +01:00
bool Ack::wasLocalAcked(uint32_t seq)
2020-01-27 17:18:33 +01:00
{
if (seqgt(seq, peerAcks[0]))
return false;
uint32_t distance = peerAcks[0] - seq;
if (distance >= 0 && distance <= 32)
{
return peerAcks[distance];
}
return false;
2020-01-27 19:53:32 +01:00
}
bool Ack::ackRemoteSeq(uint32_t ackId)
{
// Duplicate and moving window check
if (seqgt(ackId, lastRemoteSeq - MAX_RECENT_PACKETS))
{
if (find(recentIncomingSeqs.begin(), recentIncomingSeqs.end(), ackId) != recentIncomingSeqs.end())
{
LOGW("Received duplicated packet for seq %u", ackId);
return false;
}
recentIncomingSeqs.push_front(ackId);
recentIncomingSeqs.pop_back();
if (seqgt(ackId, lastRemoteSeq))
lastRemoteSeq = ackId;
}
else
{
LOGW("Packet %u is out of order and too late", ackId);
return false;
}
return true;
}
uint32_t Ack::getRemoteAckMask()
{
uint32_t acks = 0;
uint32_t distance;
for (const uint32_t &seq : recentIncomingSeqs)
{
if (!seq)
break;
distance = lastRemoteSeq - seq;
if (distance > 0 && distance <= 32)
{
acks |= (1 << (32 - distance));
}
}
return acks;
2020-01-27 17:18:33 +01:00
}