mirror of
https://github.com/danog/libtgvoip.git
synced 2024-11-30 04:39:03 +01:00
Fix legaacy support
This commit is contained in:
parent
bb62971f5f
commit
0dc1e6c96d
@ -187,7 +187,7 @@ public:
|
|||||||
setNetworkType(initialNetworkType);
|
setNetworkType(initialNetworkType);
|
||||||
|
|
||||||
controller_->SetEncryptionKey(encryptionKey.value, encryptionKey.isOutgoing);
|
controller_->SetEncryptionKey(encryptionKey.value, encryptionKey.isOutgoing);
|
||||||
controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, 110);
|
controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, config.maxApiLayer);
|
||||||
|
|
||||||
controller_->Start();
|
controller_->Start();
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
//#define LOG_PACKETS 1
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ int64_t VoIPController::GetPreferredRelayID()
|
|||||||
|
|
||||||
void VoIPController::SetRemoteEndpoints(vector<Endpoint> endpoints, bool allowP2p, int32_t connectionMaxLayer)
|
void VoIPController::SetRemoteEndpoints(vector<Endpoint> endpoints, bool allowP2p, int32_t connectionMaxLayer)
|
||||||
{
|
{
|
||||||
connectionMaxLayer = 110;
|
|
||||||
LOGW("Set remote endpoints, allowP2P=%d, connectionMaxLayer=%u", allowP2p ? 1 : 0, connectionMaxLayer);
|
LOGW("Set remote endpoints, allowP2P=%d, connectionMaxLayer=%u", allowP2p ? 1 : 0, connectionMaxLayer);
|
||||||
assert(!runReceiver);
|
assert(!runReceiver);
|
||||||
preferredRelay = 0;
|
preferredRelay = 0;
|
||||||
|
@ -38,7 +38,9 @@ void VoIPController::SendPacket(OutgoingPacket &&pkt, double retryInterval, doub
|
|||||||
if (ver.isNew())
|
if (ver.isNew())
|
||||||
{
|
{
|
||||||
packet.prepare(pm, currentExtras, endpoint.id);
|
packet.prepare(pm, currentExtras, endpoint.id);
|
||||||
//LOGW("Sending outgoing packet: %s", packet.print().c_str());
|
#ifdef LOG_PACKETS
|
||||||
|
LOGW("Sending outgoing packet: %s", packet.print().c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
//BufferOutputStream out(packet.getSize()); // Can precalc, should check if it's worth it
|
//BufferOutputStream out(packet.getSize()); // Can precalc, should check if it's worth it
|
||||||
BufferOutputStream out(1500);
|
BufferOutputStream out(1500);
|
||||||
@ -60,7 +62,9 @@ void VoIPController::SendPacket(OutgoingPacket &&pkt, double retryInterval, doub
|
|||||||
packet.prepare(pm, currentExtras, endpoint.id, legacyPm, ver.peerVersion);
|
packet.prepare(pm, currentExtras, endpoint.id, legacyPm, ver.peerVersion);
|
||||||
uint32_t seq = packet.legacySeq;
|
uint32_t seq = packet.legacySeq;
|
||||||
|
|
||||||
LOGW("Sending (legacy) outgoing packet: %s", packet.print().c_str());
|
#ifdef LOG_PACKETS
|
||||||
|
LOGW("Sending legacy outgoing packet: %s", packet.print().c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<std::pair<Buffer, bool>> out;
|
std::vector<std::pair<Buffer, bool>> out;
|
||||||
packet.serializeLegacy(out, ver, state, callID);
|
packet.serializeLegacy(out, ver, state, callID);
|
||||||
|
@ -99,9 +99,6 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &npacket, Endpoint &src
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef LOG_PACKETS
|
|
||||||
LOGW("Got%s incoming packet: %s", packet.legacy ? " legacy" : "", packet.print().c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
packetsReceived++;
|
packetsReceived++;
|
||||||
ProcessIncomingPacket(packet, srcEndpoint);
|
ProcessIncomingPacket(packet, srcEndpoint);
|
||||||
@ -117,6 +114,10 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &npacket, Endpoint &src
|
|||||||
|
|
||||||
void VoIPController::ProcessIncomingPacket(Packet &packet, Endpoint &srcEndpoint)
|
void VoIPController::ProcessIncomingPacket(Packet &packet, Endpoint &srcEndpoint)
|
||||||
{
|
{
|
||||||
|
#ifdef LOG_PACKETS
|
||||||
|
LOGW("Got%s incoming packet: %s", packet.legacy ? " legacy" : "", packet.print().c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Use packet manager of outgoing stream
|
// Use packet manager of outgoing stream
|
||||||
PacketManager &manager = outgoingStreams[packet.legacy ? StreamId::Signaling : packet.streamId]->packetManager;
|
PacketManager &manager = outgoingStreams[packet.legacy ? StreamId::Signaling : packet.streamId]->packetManager;
|
||||||
|
|
||||||
@ -407,14 +408,13 @@ void VoIPController::ProcessExtraData(const Wrapped<Extra> &_data, Endpoint &src
|
|||||||
{
|
{
|
||||||
receivedInitAck = true;
|
receivedInitAck = true;
|
||||||
|
|
||||||
LOGE("Canceling init timeout");
|
|
||||||
messageThread.Cancel(initTimeoutID);
|
messageThread.Cancel(initTimeoutID);
|
||||||
initTimeoutID = MessageThread::INVALID_ID;
|
initTimeoutID = MessageThread::INVALID_ID;
|
||||||
LOGE("Canceled init timeout");
|
|
||||||
|
|
||||||
ver.peerVersion = data.peerVersion;
|
ver.peerVersion = data.peerVersion;
|
||||||
if (data.minVersion > PROTOCOL_VERSION || data.peerVersion < MIN_PROTOCOL_VERSION)
|
if (data.minVersion > PROTOCOL_VERSION || data.peerVersion < MIN_PROTOCOL_VERSION)
|
||||||
{
|
{
|
||||||
|
LOGE("Got incompatible protocol in initAck (minVersion %u, peerVersion %u)", data.minVersion, data.peerVersion);
|
||||||
lastError = ERROR_INCOMPATIBLE;
|
lastError = ERROR_INCOMPATIBLE;
|
||||||
|
|
||||||
SetState(STATE_FAILED);
|
SetState(STATE_FAILED);
|
||||||
|
@ -6,7 +6,7 @@ void VoIPController::SendPacketReliably(PendingOutgoingPacket &pkt, double retry
|
|||||||
{
|
{
|
||||||
ENFORCE_MSG_THREAD;
|
ENFORCE_MSG_THREAD;
|
||||||
#ifdef LOG_PACKETS
|
#ifdef LOG_PACKETS
|
||||||
LOGV("Send reliably, type=%u, len=%u, retry=%.3f, timeout=%.3f, tries=%hhu", type, unsigned(len), retryInterval, timeout, tries);
|
LOGV("Send reliably, seqNo=%hhu, streamId=%u, len=%u, retry=%.3f, timeout=%.3f, tries=%hhu", pkt.pktInfo.seq, pkt.pktInfo.streamId, unsigned(pkt.packet->Length()), retryInterval, timeout, tries);
|
||||||
#endif
|
#endif
|
||||||
reliablePackets.push_back(ReliableOutgoingPacket{std::move(pkt),
|
reliablePackets.push_back(ReliableOutgoingPacket{std::move(pkt),
|
||||||
retryInterval,
|
retryInterval,
|
||||||
|
@ -82,7 +82,7 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver)
|
|||||||
}
|
}
|
||||||
else if (type == PKT_STREAM_DATA || type == PKT_STREAM_DATA_X2 || type == PKT_STREAM_DATA_X3)
|
else if (type == PKT_STREAM_DATA || type == PKT_STREAM_DATA_X2 || type == PKT_STREAM_DATA_X3)
|
||||||
{
|
{
|
||||||
for (uint8_t count = PKT_STREAM_DATA ? 1 : PKT_STREAM_DATA_X2 ? 2 : 3; count > 0; --count)
|
for (uint8_t count = type == PKT_STREAM_DATA ? 1 : type == PKT_STREAM_DATA_X2 ? 2 : 3; count > 0; --count)
|
||||||
{
|
{
|
||||||
Packet *packet = this;
|
Packet *packet = this;
|
||||||
if (count > 1)
|
if (count > 1)
|
||||||
@ -94,15 +94,16 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver)
|
|||||||
|
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
if (!(in.TryRead(packet->streamId) &&
|
if (!(in.TryRead(flags) &&
|
||||||
in.TryRead(flags) &&
|
(flags & STREAM_DATA_FLAG_LEN16
|
||||||
flags & STREAM_DATA_FLAG_LEN16
|
? in.TryRead(len)
|
||||||
? in.TryRead(len)
|
: in.TryReadCompat<uint8_t>(len)) &&
|
||||||
: in.TryReadCompat<uint8_t>(len) &&
|
in.TryRead(packet->seq)))
|
||||||
in.TryRead(packet->seq))) // damn you autoindentation
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
packet->streamId = flags & 0x3F;
|
||||||
packet->seq /= 60; // Constant frame duration
|
packet->seq /= 60; // Constant frame duration
|
||||||
|
packet->seq += 1; // Account for seqs starting at 1
|
||||||
|
|
||||||
bool fragmented = static_cast<bool>(len & STREAM_DATA_XFLAG_FRAGMENTED);
|
bool fragmented = static_cast<bool>(len & STREAM_DATA_XFLAG_FRAGMENTED);
|
||||||
bool extraFEC = static_cast<bool>(len & STREAM_DATA_XFLAG_EXTRA_FEC);
|
bool extraFEC = static_cast<bool>(len & STREAM_DATA_XFLAG_EXTRA_FEC);
|
||||||
@ -142,7 +143,9 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
LOGW("Got unknown legacy packet type %hhu (probably new packet)", type);
|
LOGW("Got unknown legacy packet type %hhu (probably new packet)", type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -170,7 +173,9 @@ void Packet::serializeLegacy(std::vector<std::pair<Buffer, bool>> &outArray, con
|
|||||||
|
|
||||||
uint8_t type = extra.d->chooseType(ver.peerVersion);
|
uint8_t type = extra.d->chooseType(ver.peerVersion);
|
||||||
|
|
||||||
|
#ifdef LOG_PACKETS
|
||||||
LOGW("Serializing separate legacy packet of type %s", VoIPController::GetPacketTypeString(type).c_str());
|
LOGW("Serializing separate legacy packet of type %s", VoIPController::GetPacketTypeString(type).c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92))
|
if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92))
|
||||||
{
|
{
|
||||||
@ -228,7 +233,7 @@ void Packet::serializeLegacy(std::vector<std::pair<Buffer, bool>> &outArray, con
|
|||||||
}
|
}
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
LOGW("Serializing legacy data len %u", (unsigned int)data->Length());
|
//LOGW("Serializing legacy data len %u", (unsigned int)data->Length());
|
||||||
|
|
||||||
BufferOutputStream out(1500);
|
BufferOutputStream out(1500);
|
||||||
|
|
||||||
@ -253,11 +258,9 @@ void Packet::serializeLegacy(std::vector<std::pair<Buffer, bool>> &outArray, con
|
|||||||
out.WriteByte(static_cast<uint8_t>(data->Length()));
|
out.WriteByte(static_cast<uint8_t>(data->Length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.WriteInt32(seq * 60);
|
out.WriteInt32((seq - 1) * 60); // Account for seq starting at 1
|
||||||
out.WriteBytes(*data);
|
out.WriteBytes(*data);
|
||||||
|
|
||||||
//LOGE("SEND: For pts %u = seq %u, using seq %u", audioTimestampOut, audioTimestampOut/60 + 1, packetManager.getLocalSeq());
|
|
||||||
|
|
||||||
if (hasExtraFEC)
|
if (hasExtraFEC)
|
||||||
{
|
{
|
||||||
out.Write(extraECArray, ver);
|
out.Write(extraECArray, ver);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
namespace tgvoip
|
namespace tgvoip
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define PRINT_MASK(mask) (std::bitset<sizeof(mask) * 8>{mask}).to_string('-', '*').c_str()
|
||||||
#define SEQ_MAX 0xFFFFFFFF
|
#define SEQ_MAX 0xFFFFFFFF
|
||||||
|
|
||||||
inline bool seqgt(uint32_t s1, uint32_t s2)
|
inline bool seqgt(uint32_t s1, uint32_t s2)
|
||||||
@ -90,6 +91,12 @@ public:
|
|||||||
// Check if local seq was acked
|
// Check if local seq was acked
|
||||||
bool wasLocalAcked(uint32_t seq) const;
|
bool wasLocalAcked(uint32_t seq) const;
|
||||||
|
|
||||||
|
// Get last mask returned from remote
|
||||||
|
inline uint32_t getLocalAckMask() const
|
||||||
|
{
|
||||||
|
return lastAckedSeqsMask;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Seqno of last acked packet
|
// Seqno of last acked packet
|
||||||
uint32_t lastAckedSeq = 0;
|
uint32_t lastAckedSeq = 0;
|
||||||
|
@ -13,10 +13,10 @@ bool Packet::parse(const BufferInputStream &in, const VersionInfo &ver)
|
|||||||
|
|
||||||
uint16_t length = 0;
|
uint16_t length = 0;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
bool res = in.TryRead(seq) &&
|
bool res = in.TryRead(flags) &&
|
||||||
|
in.TryRead(seq) &&
|
||||||
in.TryRead(ackSeq) &&
|
in.TryRead(ackSeq) &&
|
||||||
in.TryRead(ackMask) &&
|
in.TryRead(ackMask);
|
||||||
in.TryRead(flags);
|
|
||||||
if (!res)
|
if (!res)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -76,10 +76,10 @@ void Packet::serialize(BufferOutputStream &out, const VersionInfo &ver) const
|
|||||||
if (extraSignaling)
|
if (extraSignaling)
|
||||||
flags |= Flags::ExtraSignaling;
|
flags |= Flags::ExtraSignaling;
|
||||||
|
|
||||||
|
out.WriteByte(shortStreamId | (flags << 2));
|
||||||
out.WriteUInt32(seq);
|
out.WriteUInt32(seq);
|
||||||
out.WriteUInt32(ackSeq);
|
out.WriteUInt32(ackSeq);
|
||||||
out.WriteUInt32(ackMask);
|
out.WriteUInt32(ackMask);
|
||||||
out.WriteByte(shortStreamId | (flags << 2));
|
|
||||||
|
|
||||||
if (shortStreamId == StreamId::Extended)
|
if (shortStreamId == StreamId::Extended)
|
||||||
out.WriteByte(streamId);
|
out.WriteByte(streamId);
|
||||||
@ -131,8 +131,8 @@ void Packet::prepare(PacketManager &pm, std::vector<UnacknowledgedExtraData> &cu
|
|||||||
if (pm != legacyPm)
|
if (pm != legacyPm)
|
||||||
{
|
{
|
||||||
legacySeq = legacyPm.nextLocalSeq();
|
legacySeq = legacyPm.nextLocalSeq();
|
||||||
ackSeq = pm.getLastRemoteSeq();
|
ackSeq = legacyPm.getLastRemoteSeq();
|
||||||
ackMask = pm.getRemoteAckMask();
|
ackMask = legacyPm.getRemoteAckMask();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -150,10 +150,16 @@ void Packet::prepare(PacketManager &pm, std::vector<UnacknowledgedExtraData> &cu
|
|||||||
extraSignaling.v.push_back(extra.data);
|
extraSignaling.v.push_back(extra.data);
|
||||||
if (extra.data.d->chooseType(peerVersion) == PKT_NOP)
|
if (extra.data.d->chooseType(peerVersion) == PKT_NOP)
|
||||||
{
|
{
|
||||||
|
#ifdef LOG_PACKETS
|
||||||
|
LOGW("Adding legacy seq %u to extra %s", seq, extra.data.print().c_str());
|
||||||
|
#endif
|
||||||
extra.seqs.Add(seq);
|
extra.seqs.Add(seq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef LOG_PACKETS
|
||||||
|
LOGW("Adding legacy seq %u to extra %s", tmpLegacySeq, extra.data.print().c_str());
|
||||||
|
#endif
|
||||||
extra.seqs.Add(tmpLegacySeq++);
|
extra.seqs.Add(tmpLegacySeq++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "../../net/CongestionControl.h"
|
#include "../../net/CongestionControl.h"
|
||||||
#include "../protocol/Extra.h"
|
#include "../protocol/Extra.h"
|
||||||
#include "../protocol/Interface.h"
|
#include "../protocol/Interface.h"
|
||||||
|
#include "PacketManager.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
//#include "../net/PacketSender.h"
|
//#include "../net/PacketSender.h"
|
||||||
@ -10,7 +11,6 @@
|
|||||||
namespace tgvoip
|
namespace tgvoip
|
||||||
{
|
{
|
||||||
class PacketSender;
|
class PacketSender;
|
||||||
class PacketManager;
|
|
||||||
struct PendingOutgoingPacket
|
struct PendingOutgoingPacket
|
||||||
{
|
{
|
||||||
PendingOutgoingPacket(std::shared_ptr<Buffer> &&_packet, CongestionControlPacket &&_pktInfo, int64_t _endpoint) : packet(std::move(_packet)),
|
PendingOutgoingPacket(std::shared_ptr<Buffer> &&_packet, CongestionControlPacket &&_pktInfo, int64_t _endpoint) : packet(std::move(_packet)),
|
||||||
@ -142,7 +142,11 @@ public:
|
|||||||
{
|
{
|
||||||
std::stringstream res;
|
std::stringstream res;
|
||||||
res << ((data && data->Length()) ? "Data packet" : extraEC ? "EC packet" : extraSignaling ? "Signaling packet" : nopPacket ? "NOP packet" : "Empty packet");
|
res << ((data && data->Length()) ? "Data packet" : extraEC ? "EC packet" : extraSignaling ? "Signaling packet" : nopPacket ? "NOP packet" : "Empty packet");
|
||||||
res << " (seq=" << seq << ", legacySeq=" << legacySeq << ", streamId=" << int(streamId) << ")";
|
res << " (seq=" << seq << ", legacySeq=" << legacySeq;
|
||||||
|
#ifdef LOG_PACKETS
|
||||||
|
res << ", ackSeq=" << ackSeq << ", ackMask=" << PRINT_MASK(ackMask);
|
||||||
|
#endif
|
||||||
|
res << ", streamId=" << int(streamId) << ")";
|
||||||
if (extraEC)
|
if (extraEC)
|
||||||
res << "; extraEC";
|
res << "; extraEC";
|
||||||
if (extraSignaling)
|
if (extraSignaling)
|
||||||
@ -172,6 +176,7 @@ public:
|
|||||||
streamId = 0;
|
streamId = 0;
|
||||||
data = nullptr;
|
data = nullptr;
|
||||||
recvTS = 0;
|
recvTS = 0;
|
||||||
|
legacy = false;
|
||||||
for (auto &v : extraEC) {
|
for (auto &v : extraEC) {
|
||||||
v.d = nullptr;
|
v.d = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// Try unifying all flags, lengths and so on
|
// Try unifying all flags, lengths and so on
|
||||||
|
|
||||||
packet$_
|
packet$_
|
||||||
seq:# ackSeq:# ackMask:# // Different sequence for each streamId
|
|
||||||
|
|
||||||
streamId:(## 2) // Max 2 streams, we don't need much anyway (0 and 3 are reserved values)
|
streamId:(## 2) // Max 2 streams, we don't need much anyway (0 and 3 are reserved values)
|
||||||
// If 0, is a pure-service message
|
// If 0, is a pure-service message
|
||||||
// If 1, is an audio packet
|
// If 1, is an audio packet
|
||||||
@ -11,6 +9,8 @@ packet$_
|
|||||||
// If 3, is packet from one of the group call streams
|
// If 3, is packet from one of the group call streams
|
||||||
flags:(## 6)
|
flags:(## 6)
|
||||||
|
|
||||||
|
seq:# ackSeq:# ackMask:# // Different sequence for each streamId
|
||||||
|
|
||||||
streamIdExtended:(streamId == 3 ? (## 8) : false) // Extended stream ID for group calls
|
streamIdExtended:(streamId == 3 ? (## 8) : false) // Extended stream ID for group calls
|
||||||
|
|
||||||
length:(## flags.0 ? 11 : (streamId > 0 ? 8 : 0))
|
length:(## flags.0 ? 11 : (streamId > 0 ? 8 : 0))
|
||||||
|
Loading…
Reference in New Issue
Block a user