2020-01-27 19:53:32 +01:00
|
|
|
#pragma once
|
2020-01-27 17:18:33 +01:00
|
|
|
#include <atomic>
|
2020-01-28 21:45:56 +01:00
|
|
|
#include <bitset>
|
2020-01-27 19:53:32 +01:00
|
|
|
#include "PacketStructs.h"
|
2020-01-27 17:18:33 +01:00
|
|
|
|
|
|
|
namespace tgvoip
|
|
|
|
{
|
2020-01-28 13:18:38 +01:00
|
|
|
|
|
|
|
#define SEQ_MAX 0xFFFFFFFF
|
|
|
|
|
|
|
|
inline bool seqgt(uint32_t s1, uint32_t s2)
|
|
|
|
{
|
|
|
|
return ((s1 > s2) && (s1 - s2 <= SEQ_MAX / 2)) || ((s1 < s2) && (s2 - s1 > SEQ_MAX / 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool seqgte(uint32_t s1, uint32_t s2)
|
|
|
|
{
|
|
|
|
return s1 == s2 || seqgt(s1, s2);
|
|
|
|
}
|
|
|
|
|
2020-01-27 19:53:32 +01:00
|
|
|
// Local and remote packet history management
|
2020-01-28 21:45:56 +01:00
|
|
|
class PacketManager
|
2020-01-27 19:53:32 +01:00
|
|
|
{
|
2020-01-28 21:45:56 +01:00
|
|
|
public:
|
|
|
|
PacketManager() = default;
|
|
|
|
virtual ~PacketManager() = default;
|
2020-01-27 19:53:32 +01:00
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
/* Local seqno generation */
|
2020-01-27 19:53:32 +01:00
|
|
|
|
|
|
|
// Get next local seqno
|
|
|
|
inline uint32_t nextLocalSeq()
|
2020-01-27 17:18:33 +01:00
|
|
|
{
|
2020-01-27 19:53:32 +01:00
|
|
|
return seq++;
|
|
|
|
}
|
|
|
|
|
2020-01-28 13:18:38 +01:00
|
|
|
// Get current local seqno
|
|
|
|
inline uint32_t getLocalSeq()
|
|
|
|
{
|
|
|
|
return seq;
|
|
|
|
}
|
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
inline uint32_t getLastSentSeq()
|
|
|
|
{
|
|
|
|
return lastSentSeq;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Seqno of last sent local packet
|
|
|
|
uint32_t lastSentSeq = 0;
|
|
|
|
|
2020-01-28 13:18:38 +01:00
|
|
|
private:
|
2020-01-27 19:53:32 +01:00
|
|
|
// Stream-specific local seqno
|
|
|
|
std::atomic<uint32_t> seq = ATOMIC_VAR_INIT(1);
|
|
|
|
|
2020-01-28 13:18:38 +01:00
|
|
|
public:
|
2020-01-28 21:45:56 +01:00
|
|
|
/* Local seqno acks */
|
2020-01-27 19:53:32 +01:00
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
// Ack specified local seq + up to 32 seqs ago, specified by mask
|
|
|
|
void ackLocal(uint32_t ackId, uint32_t mask);
|
|
|
|
|
|
|
|
// Check if local seq was acked
|
|
|
|
bool wasLocalAcked(uint32_t seq);
|
2020-01-27 19:53:32 +01:00
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
inline uint32_t getLastAckedSeq() const
|
|
|
|
{
|
|
|
|
return lastAckedSeq;
|
|
|
|
}
|
2020-01-27 19:53:32 +01:00
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
private:
|
|
|
|
// Seqno of last acked packet
|
|
|
|
uint32_t lastAckedSeq = 0;
|
|
|
|
|
|
|
|
// Status list of acked local seqnos, excluding the seq explicitly present in the packet, up to 32 seqs ago
|
|
|
|
uint32_t lastAckedSeqsMask = 0;
|
|
|
|
|
|
|
|
public:
|
2020-01-27 19:53:32 +01:00
|
|
|
/* Remote seqno ack */
|
|
|
|
// Ack specified remote seq, returns false if too old or dupe
|
|
|
|
bool ackRemoteSeq(uint32_t ackId);
|
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
// Ack remote seqs older than the specified seq
|
|
|
|
inline void ackRemoteSeqsOlderThan(uint32_t seq)
|
|
|
|
{
|
|
|
|
lastRemoteSeqsMask |= 0xFFFFFFFF << (lastRemoteSeq - seq);
|
|
|
|
}
|
|
|
|
|
2020-01-27 19:53:32 +01:00
|
|
|
// Get ack mask for remote packets
|
2020-01-28 21:45:56 +01:00
|
|
|
inline uint32_t getRemoteAckMask()
|
|
|
|
{
|
|
|
|
return lastRemoteSeqsMask;
|
|
|
|
}
|
2020-01-27 19:53:32 +01:00
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
inline uint32_t getLastRemoteSeq()
|
|
|
|
{
|
|
|
|
return lastRemoteSeq;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2020-01-27 19:53:32 +01:00
|
|
|
// Seqno of last received remote packet
|
|
|
|
uint32_t lastRemoteSeq = 0;
|
|
|
|
|
|
|
|
// Recent incoming remote packets
|
2020-01-28 21:45:56 +01:00
|
|
|
uint32_t lastRemoteSeqsMask;
|
2020-01-27 19:53:32 +01:00
|
|
|
};
|
|
|
|
} // namespace tgvoip
|