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-03-25 15:49:13 +01:00
|
|
|
#include <vector>
|
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-03-25 15:49:13 +01:00
|
|
|
class RecentOutgoingPacket;
|
|
|
|
class PendingOutgoingPacket;
|
|
|
|
class Packet;
|
2020-01-27 19:53:32 +01:00
|
|
|
// Local and remote packet history management
|
2020-03-21 21:33:51 +01:00
|
|
|
class PacketManager final
|
2020-01-27 19:53:32 +01:00
|
|
|
{
|
2020-01-28 21:45:56 +01:00
|
|
|
public:
|
2020-03-21 21:33:51 +01:00
|
|
|
PacketManager() = delete;
|
|
|
|
PacketManager(uint8_t transportId);
|
2020-01-27 19:53:32 +01:00
|
|
|
|
2020-03-24 12:15:04 +01:00
|
|
|
bool operator==(const PacketManager &other)
|
|
|
|
{
|
|
|
|
return transportId == other.transportId;
|
|
|
|
}
|
|
|
|
bool operator!=(const PacketManager &other)
|
|
|
|
{
|
|
|
|
return transportId != other.transportId;
|
|
|
|
}
|
2020-01-28 23:45:47 +01:00
|
|
|
// Transport ID for multiplexing
|
2020-03-21 21:33:51 +01:00
|
|
|
uint8_t transportId;
|
2020-01-28 23:45:47 +01:00
|
|
|
|
|
|
|
public:
|
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
|
2020-03-24 12:15:04 +01:00
|
|
|
inline uint32_t getLocalSeq() const
|
2020-01-28 13:18:38 +01:00
|
|
|
{
|
|
|
|
return seq;
|
|
|
|
}
|
|
|
|
|
2020-03-22 21:25:02 +01:00
|
|
|
inline void setLocalSeq(uint32_t _seq)
|
|
|
|
{
|
|
|
|
seq = _seq;
|
|
|
|
}
|
|
|
|
|
2020-03-24 15:07:56 +01:00
|
|
|
inline uint32_t getLastSentSeq() const
|
2020-01-28 21:45:56 +01:00
|
|
|
{
|
|
|
|
return lastSentSeq;
|
|
|
|
}
|
|
|
|
|
2020-01-28 23:45:47 +01:00
|
|
|
inline void setLastSentSeq(uint32_t lastSentSeq)
|
|
|
|
{
|
|
|
|
this->lastSentSeq = lastSentSeq;
|
|
|
|
}
|
|
|
|
|
2020-01-28 21:45:56 +01:00
|
|
|
// 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-03-24 15:07:56 +01:00
|
|
|
inline uint32_t getLastAckedSeq() const
|
|
|
|
{
|
|
|
|
return lastAckedSeq;
|
|
|
|
}
|
|
|
|
|
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
|
2020-03-24 12:15:04 +01:00
|
|
|
bool wasLocalAcked(uint32_t seq) const;
|
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 */
|
2020-03-24 17:10:40 +01:00
|
|
|
// Ack specified remote packet, returns false if too old or dupe
|
|
|
|
bool ackRemoteSeq(const Packet &pkt);
|
|
|
|
|
2020-01-27 19:53:32 +01:00
|
|
|
// Ack specified remote seq, returns false if too old or dupe
|
2020-03-24 17:10:40 +01:00
|
|
|
bool ackRemoteSeq(const uint32_t ackId);
|
2020-01-27 19:53:32 +01:00
|
|
|
|
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-03-24 12:15:04 +01:00
|
|
|
inline uint32_t getRemoteAckMask() const
|
2020-01-28 21:45:56 +01:00
|
|
|
{
|
|
|
|
return lastRemoteSeqsMask;
|
|
|
|
}
|
2020-01-27 19:53:32 +01:00
|
|
|
|
2020-03-24 17:10:40 +01:00
|
|
|
// Get last remote seqno
|
2020-03-24 12:15:04 +01:00
|
|
|
inline uint32_t getLastRemoteSeq() const
|
2020-01-28 21:45:56 +01:00
|
|
|
{
|
|
|
|
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-29 15:52:43 +01:00
|
|
|
|
|
|
|
public: // Recent outgoing packet list
|
2020-03-24 15:07:56 +01:00
|
|
|
std::vector<RecentOutgoingPacket> &getRecentOutgoingPackets();
|
|
|
|
void addRecentOutgoingPacket(const PendingOutgoingPacket &pkt);
|
|
|
|
void addRecentOutgoingPacket(RecentOutgoingPacket &&pkt);
|
2020-03-25 15:49:13 +01:00
|
|
|
|
2020-01-29 15:52:43 +01:00
|
|
|
private:
|
|
|
|
// Recent ougoing packets
|
|
|
|
std::vector<RecentOutgoingPacket> recentOutgoingPackets;
|
2020-01-27 19:53:32 +01:00
|
|
|
};
|
|
|
|
} // namespace tgvoip
|