diff --git a/TgVoip.cpp b/TgVoip.cpp index ec69d53..a6bd11a 100755 --- a/TgVoip.cpp +++ b/TgVoip.cpp @@ -187,7 +187,7 @@ public: setNetworkType(initialNetworkType); controller_->SetEncryptionKey(encryptionKey.value, encryptionKey.isOutgoing); - controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, 110); + controller_->SetRemoteEndpoints(mappedEndpoints, config.enableP2P, config.maxApiLayer); controller_->Start(); diff --git a/VoIPController.h b/VoIPController.h index 7d069d6..72de04e 100755 --- a/VoIPController.h +++ b/VoIPController.h @@ -5,6 +5,7 @@ // #pragma once +//#define LOG_PACKETS 1 #include diff --git a/controller/protocol/Endpoints.cpp b/controller/protocol/Endpoints.cpp index 0636aa5..14e8755 100644 --- a/controller/protocol/Endpoints.cpp +++ b/controller/protocol/Endpoints.cpp @@ -43,7 +43,6 @@ int64_t VoIPController::GetPreferredRelayID() void VoIPController::SetRemoteEndpoints(vector endpoints, bool allowP2p, int32_t connectionMaxLayer) { - connectionMaxLayer = 110; LOGW("Set remote endpoints, allowP2P=%d, connectionMaxLayer=%u", allowP2p ? 1 : 0, connectionMaxLayer); assert(!runReceiver); preferredRelay = 0; diff --git a/controller/protocol/NetworkAPI.cpp b/controller/protocol/NetworkAPI.cpp index e05bb08..a84c8fa 100644 --- a/controller/protocol/NetworkAPI.cpp +++ b/controller/protocol/NetworkAPI.cpp @@ -38,7 +38,9 @@ void VoIPController::SendPacket(OutgoingPacket &&pkt, double retryInterval, doub if (ver.isNew()) { 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(1500); @@ -60,7 +62,9 @@ void VoIPController::SendPacket(OutgoingPacket &&pkt, double retryInterval, doub packet.prepare(pm, currentExtras, endpoint.id, legacyPm, ver.peerVersion); 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> out; packet.serializeLegacy(out, ver, state, callID); diff --git a/controller/protocol/Protocol.cpp b/controller/protocol/Protocol.cpp index 4c61de5..21dba4f 100644 --- a/controller/protocol/Protocol.cpp +++ b/controller/protocol/Protocol.cpp @@ -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++; ProcessIncomingPacket(packet, srcEndpoint); @@ -117,6 +114,10 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &npacket, Endpoint &src 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 PacketManager &manager = outgoingStreams[packet.legacy ? StreamId::Signaling : packet.streamId]->packetManager; @@ -407,14 +408,13 @@ void VoIPController::ProcessExtraData(const Wrapped &_data, Endpoint &src { receivedInitAck = true; - LOGE("Canceling init timeout"); messageThread.Cancel(initTimeoutID); initTimeoutID = MessageThread::INVALID_ID; - LOGE("Canceled init timeout"); ver.peerVersion = data.peerVersion; 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; SetState(STATE_FAILED); diff --git a/controller/protocol/Reliable.cpp b/controller/protocol/Reliable.cpp index b51040b..b8dc0b4 100644 --- a/controller/protocol/Reliable.cpp +++ b/controller/protocol/Reliable.cpp @@ -6,7 +6,7 @@ void VoIPController::SendPacketReliably(PendingOutgoingPacket &pkt, double retry { ENFORCE_MSG_THREAD; #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 reliablePackets.push_back(ReliableOutgoingPacket{std::move(pkt), retryInterval, diff --git a/controller/protocol/packets/Legacy.cpp b/controller/protocol/packets/Legacy.cpp index 8689827..584e6c9 100644 --- a/controller/protocol/packets/Legacy.cpp +++ b/controller/protocol/packets/Legacy.cpp @@ -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) { - 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; if (count > 1) @@ -94,15 +94,16 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver) uint8_t flags; uint16_t len; - if (!(in.TryRead(packet->streamId) && - in.TryRead(flags) && - flags & STREAM_DATA_FLAG_LEN16 - ? in.TryRead(len) - : in.TryReadCompat(len) && - in.TryRead(packet->seq))) // damn you autoindentation + if (!(in.TryRead(flags) && + (flags & STREAM_DATA_FLAG_LEN16 + ? in.TryRead(len) + : in.TryReadCompat(len)) && + in.TryRead(packet->seq))) return false; + packet->streamId = flags & 0x3F; packet->seq /= 60; // Constant frame duration + packet->seq += 1; // Account for seqs starting at 1 bool fragmented = static_cast(len & STREAM_DATA_XFLAG_FRAGMENTED); bool extraFEC = static_cast(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); return false; } @@ -170,7 +173,9 @@ void Packet::serializeLegacy(std::vector> &outArray, con uint8_t type = extra.d->chooseType(ver.peerVersion); +#ifdef LOG_PACKETS LOGW("Serializing separate legacy packet of type %s", VoIPController::GetPacketTypeString(type).c_str()); +#endif if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92)) { @@ -228,7 +233,7 @@ void Packet::serializeLegacy(std::vector> &outArray, con } 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); @@ -253,11 +258,9 @@ void Packet::serializeLegacy(std::vector> &outArray, con out.WriteByte(static_cast(data->Length())); } - out.WriteInt32(seq * 60); + out.WriteInt32((seq - 1) * 60); // Account for seq starting at 1 out.WriteBytes(*data); - //LOGE("SEND: For pts %u = seq %u, using seq %u", audioTimestampOut, audioTimestampOut/60 + 1, packetManager.getLocalSeq()); - if (hasExtraFEC) { out.Write(extraECArray, ver); diff --git a/controller/protocol/packets/PacketManager.h b/controller/protocol/packets/PacketManager.h index a893a1a..704d764 100644 --- a/controller/protocol/packets/PacketManager.h +++ b/controller/protocol/packets/PacketManager.h @@ -6,6 +6,7 @@ namespace tgvoip { +#define PRINT_MASK(mask) (std::bitset{mask}).to_string('-', '*').c_str() #define SEQ_MAX 0xFFFFFFFF inline bool seqgt(uint32_t s1, uint32_t s2) @@ -90,6 +91,12 @@ public: // Check if local seq was acked bool wasLocalAcked(uint32_t seq) const; + // Get last mask returned from remote + inline uint32_t getLocalAckMask() const + { + return lastAckedSeqsMask; + } + private: // Seqno of last acked packet uint32_t lastAckedSeq = 0; diff --git a/controller/protocol/packets/PacketStructs.cpp b/controller/protocol/packets/PacketStructs.cpp index 1cce4fa..addd215 100644 --- a/controller/protocol/packets/PacketStructs.cpp +++ b/controller/protocol/packets/PacketStructs.cpp @@ -13,10 +13,10 @@ bool Packet::parse(const BufferInputStream &in, const VersionInfo &ver) uint16_t length = 0; uint8_t flags; - bool res = in.TryRead(seq) && + bool res = in.TryRead(flags) && + in.TryRead(seq) && in.TryRead(ackSeq) && - in.TryRead(ackMask) && - in.TryRead(flags); + in.TryRead(ackMask); if (!res) return false; @@ -76,10 +76,10 @@ void Packet::serialize(BufferOutputStream &out, const VersionInfo &ver) const if (extraSignaling) flags |= Flags::ExtraSignaling; + out.WriteByte(shortStreamId | (flags << 2)); out.WriteUInt32(seq); out.WriteUInt32(ackSeq); out.WriteUInt32(ackMask); - out.WriteByte(shortStreamId | (flags << 2)); if (shortStreamId == StreamId::Extended) out.WriteByte(streamId); @@ -131,8 +131,8 @@ void Packet::prepare(PacketManager &pm, std::vector &cu if (pm != legacyPm) { legacySeq = legacyPm.nextLocalSeq(); - ackSeq = pm.getLastRemoteSeq(); - ackMask = pm.getRemoteAckMask(); + ackSeq = legacyPm.getLastRemoteSeq(); + ackMask = legacyPm.getRemoteAckMask(); } else { @@ -150,10 +150,16 @@ void Packet::prepare(PacketManager &pm, std::vector &cu extraSignaling.v.push_back(extra.data); 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); } else { +#ifdef LOG_PACKETS + LOGW("Adding legacy seq %u to extra %s", tmpLegacySeq, extra.data.print().c_str()); +#endif extra.seqs.Add(tmpLegacySeq++); } } diff --git a/controller/protocol/packets/PacketStructs.h b/controller/protocol/packets/PacketStructs.h index 969022a..8bb42a6 100644 --- a/controller/protocol/packets/PacketStructs.h +++ b/controller/protocol/packets/PacketStructs.h @@ -3,6 +3,7 @@ #include "../../net/CongestionControl.h" #include "../protocol/Extra.h" #include "../protocol/Interface.h" +#include "PacketManager.h" #include #include //#include "../net/PacketSender.h" @@ -10,7 +11,6 @@ namespace tgvoip { class PacketSender; -class PacketManager; struct PendingOutgoingPacket { PendingOutgoingPacket(std::shared_ptr &&_packet, CongestionControlPacket &&_pktInfo, int64_t _endpoint) : packet(std::move(_packet)), @@ -142,7 +142,11 @@ public: { std::stringstream res; 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) res << "; extraEC"; if (extraSignaling) @@ -172,6 +176,7 @@ public: streamId = 0; data = nullptr; recvTS = 0; + legacy = false; for (auto &v : extraEC) { v.d = nullptr; } diff --git a/schemeNew.tlb b/schemeNew.tlb index 89ae0db..1a7c174 100644 --- a/schemeNew.tlb +++ b/schemeNew.tlb @@ -2,8 +2,6 @@ // Try unifying all flags, lengths and so on 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) // If 0, is a pure-service message // If 1, is an audio packet @@ -11,6 +9,8 @@ packet$_ // If 3, is packet from one of the group call streams flags:(## 6) + seq:# ackSeq:# ackMask:# // Different sequence for each streamId + streamIdExtended:(streamId == 3 ? (## 8) : false) // Extended stream ID for group calls length:(## flags.0 ? 11 : (streamId > 0 ? 8 : 0))