1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-26 12:14:39 +01:00

Finish refactoring packet structure

This commit is contained in:
Daniil Gentili 2020-03-21 15:08:03 +01:00
parent c81037e7ca
commit 4a1a910d0a
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
29 changed files with 690 additions and 401 deletions

10
.clang-format Normal file
View File

@ -0,0 +1,10 @@
BasedOnStyle: LLVM
UseTab: Never
IndentWidth: 4
TabWidth: 4
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
ColumnLimit: 0
AccessModifierOffset: -4

View File

@ -21,7 +21,7 @@ controller/audio/AudioPacketSender.cpp \
controller/net/PacketReassembler.cpp \
controller/protocol/PacketManager.cpp \
controller/protocol/PacketStructs.cpp \
controller/protocol/packets/Extra.cpp \
controller/protocol/protocol/Extra.cpp \
VoIPGroupController.cpp \
VoIPServerConfig.cpp \
audio/AudioIO.cpp \

View File

@ -820,7 +820,7 @@ am__libtgvoip_la_SOURCES_DIST = TgVoip.cpp VoIPController.cpp \
controller/net/PacketReassembler.cpp \
controller/protocol/PacketManager.cpp \
controller/protocol/PacketStructs.cpp \
controller/protocol/packets/Extra.cpp VoIPGroupController.cpp \
controller/protocol/protocol/Extra.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
@ -1763,7 +1763,7 @@ am__objects_12 = TgVoip.lo VoIPController.lo tools/Buffers.lo \
controller/net/PacketReassembler.lo \
controller/protocol/PacketManager.lo \
controller/protocol/PacketStructs.lo \
controller/protocol/packets/Extra.lo VoIPGroupController.lo \
controller/protocol/protocol/Extra.lo VoIPGroupController.lo \
VoIPServerConfig.lo audio/AudioIO.lo audio/AudioInput.lo \
audio/AudioOutput.lo audio/Resampler.lo \
audio/AudioInputTester.lo os/posix/NetworkSocketPosix.lo \
@ -2081,7 +2081,7 @@ am__depfiles_remade = ./$(DEPDIR)/TgVoip.Plo \
controller/net/$(DEPDIR)/PacketReassembler.Plo \
controller/protocol/$(DEPDIR)/PacketManager.Plo \
controller/protocol/$(DEPDIR)/PacketStructs.Plo \
controller/protocol/packets/$(DEPDIR)/Extra.Plo \
controller/protocol/protocol/$(DEPDIR)/Extra.Plo \
os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo \
os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo \
os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo \
@ -2401,7 +2401,7 @@ SRC = TgVoip.cpp VoIPController.cpp tools/Buffers.cpp \
controller/net/PacketReassembler.cpp \
controller/protocol/PacketManager.cpp \
controller/protocol/PacketStructs.cpp \
controller/protocol/packets/Extra.cpp VoIPGroupController.cpp \
controller/protocol/protocol/Extra.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
@ -2582,15 +2582,15 @@ controller/protocol/PacketManager.lo: \
controller/protocol/PacketStructs.lo: \
controller/protocol/$(am__dirstamp) \
controller/protocol/$(DEPDIR)/$(am__dirstamp)
controller/protocol/packets/$(am__dirstamp):
@$(MKDIR_P) controller/protocol/packets
@: > controller/protocol/packets/$(am__dirstamp)
controller/protocol/packets/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) controller/protocol/packets/$(DEPDIR)
@: > controller/protocol/packets/$(DEPDIR)/$(am__dirstamp)
controller/protocol/packets/Extra.lo: \
controller/protocol/packets/$(am__dirstamp) \
controller/protocol/packets/$(DEPDIR)/$(am__dirstamp)
controller/protocol/protocol/$(am__dirstamp):
@$(MKDIR_P) controller/protocol/protocol
@: > controller/protocol/protocol/$(am__dirstamp)
controller/protocol/protocol/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) controller/protocol/protocol/$(DEPDIR)
@: > controller/protocol/protocol/$(DEPDIR)/$(am__dirstamp)
controller/protocol/protocol/Extra.lo: \
controller/protocol/protocol/$(am__dirstamp) \
controller/protocol/protocol/$(DEPDIR)/$(am__dirstamp)
audio/$(am__dirstamp):
@$(MKDIR_P) audio
@: > audio/$(am__dirstamp)
@ -3747,8 +3747,8 @@ mostlyclean-compile:
-rm -f controller/net/*.lo
-rm -f controller/protocol/*.$(OBJEXT)
-rm -f controller/protocol/*.lo
-rm -f controller/protocol/packets/*.$(OBJEXT)
-rm -f controller/protocol/packets/*.lo
-rm -f controller/protocol/protocol/*.$(OBJEXT)
-rm -f controller/protocol/protocol/*.lo
-rm -f os/darwin/*.$(OBJEXT)
-rm -f os/darwin/*.lo
-rm -f os/linux/*.$(OBJEXT)
@ -4062,7 +4062,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/PacketReassembler.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/protocol/$(DEPDIR)/PacketManager.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/protocol/$(DEPDIR)/PacketStructs.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/protocol/packets/$(DEPDIR)/Extra.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/protocol/protocol/$(DEPDIR)/Extra.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo@am__quote@ # am--include-marker
@ -4272,7 +4272,7 @@ clean-libtool:
-rm -rf controller/media/.libs controller/media/_libs
-rm -rf controller/net/.libs controller/net/_libs
-rm -rf controller/protocol/.libs controller/protocol/_libs
-rm -rf controller/protocol/packets/.libs controller/protocol/packets/_libs
-rm -rf controller/protocol/protocol/.libs controller/protocol/protocol/_libs
-rm -rf os/darwin/.libs os/darwin/_libs
-rm -rf os/linux/.libs os/linux/_libs
-rm -rf os/posix/.libs os/posix/_libs
@ -4581,8 +4581,8 @@ distclean-generic:
-rm -f controller/net/$(am__dirstamp)
-rm -f controller/protocol/$(DEPDIR)/$(am__dirstamp)
-rm -f controller/protocol/$(am__dirstamp)
-rm -f controller/protocol/packets/$(DEPDIR)/$(am__dirstamp)
-rm -f controller/protocol/packets/$(am__dirstamp)
-rm -f controller/protocol/protocol/$(DEPDIR)/$(am__dirstamp)
-rm -f controller/protocol/protocol/$(am__dirstamp)
-rm -f os/darwin/$(DEPDIR)/$(am__dirstamp)
-rm -f os/darwin/$(am__dirstamp)
-rm -f os/linux/$(DEPDIR)/$(am__dirstamp)
@ -4957,7 +4957,7 @@ distclean: distclean-am
-rm -f controller/net/$(DEPDIR)/PacketReassembler.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketManager.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketStructs.Plo
-rm -f controller/protocol/packets/$(DEPDIR)/Extra.Plo
-rm -f controller/protocol/protocol/$(DEPDIR)/Extra.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo
-rm -f os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo
@ -5329,7 +5329,7 @@ maintainer-clean: maintainer-clean-am
-rm -f controller/net/$(DEPDIR)/PacketReassembler.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketManager.Plo
-rm -f controller/protocol/$(DEPDIR)/PacketStructs.Plo
-rm -f controller/protocol/packets/$(DEPDIR)/Extra.Plo
-rm -f controller/protocol/protocol/$(DEPDIR)/Extra.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnitOSX.Plo
-rm -f os/darwin/$(DEPDIR)/AudioOutputAudioUnit.Plo

View File

@ -6,6 +6,12 @@
#pragma once
#if defined HAVE_CONFIG_H || defined TGVOIP_USE_INSTALLED_OPUS
#include <opus/opus.h>
#else
#include <opus/opus.h>
#endif
#ifndef _WIN32
#include <arpa/inet.h>
#include <netinet/in.h>
@ -47,11 +53,6 @@
#include "tools/utils.h"
#include "controller/PrivateDefines.h"
#if defined HAVE_CONFIG_H || defined TGVOIP_USE_INSTALLED_OPUS
#include <opus/opus.h>
#else
#include <opus/opus.h>
#endif
#define LIBTGVOIP_VERSION "2.5"

View File

@ -95,7 +95,7 @@ void VoIPGroupController::AddGroupCallParticipant(int32_t userID, unsigned char
{
shared_ptr<Stream> &s = *_s;
s->userID = userID;
if (s->type == STREAM_TYPE_AUDIO && s->codec == CODEC_OPUS && !audioStreamID)
if (s->type == StreamInfo::Type::Audio && s->codec == Codec::Opus && !audioStreamID)
{
audioStreamID = s->id;
s->jitterBuffer = make_shared<JitterBuffer>(s->frameDuration);
@ -165,10 +165,10 @@ vector<shared_ptr<VoIPController::Stream>> VoIPGroupController::DeserializeStrea
BufferInputStream inner = in.GetPartBuffer(len, true);
shared_ptr<Stream> s = make_shared<Stream>();
s->id = inner.ReadByte();
s->type = static_cast<StreamType>(inner.ReadByte());
s->type = static_cast<StreamInfo::Type>(inner.ReadByte());
s->codec = (uint32_t)inner.ReadInt32();
uint32_t flags = (uint32_t)inner.ReadInt32();
s->enabled = (flags & STREAM_FLAG_ENABLED) == STREAM_FLAG_ENABLED;
s->enabled = flags & ExtraStreamFlags::Flags::Enabled;
s->frameDuration = (uint16_t)inner.ReadInt16();
res.push_back(s);
}
@ -221,9 +221,9 @@ size_t VoIPGroupController::GetInitialStreams(unsigned char *buf, size_t size)
s.WriteInt16(12); // this object length
s.WriteByte(1); // stream id
s.WriteByte(STREAM_TYPE_AUDIO);
s.WriteInt32(CODEC_OPUS);
s.WriteInt32(STREAM_FLAG_ENABLED | STREAM_FLAG_DTX); // flags
s.WriteByte(StreamInfo::Type::Audio);
s.WriteInt32(Codec::Opus);
s.WriteInt32(ExtraStreamFlags::Flags::Enabled | ExtraStreamFlags::Flags::Dtx); // flags
s.WriteInt16(60); // frame duration
return s.GetLength();
@ -509,7 +509,7 @@ void VoIPGroupController::SetParticipantVolume(int32_t userID, float volume)
{
for (vector<shared_ptr<Stream>>::iterator s = p->streams.begin(); s != p->streams.end(); ++s)
{
if ((*s)->type == STREAM_TYPE_AUDIO)
if ((*s)->type == StreamInfo::Type::Audio)
{
if ((*s)->decoder)
{
@ -544,7 +544,7 @@ void VoIPGroupController::SerializeAndUpdateOutgoingStreams()
o.WriteByte((*s)->id);
o.WriteByte((*s)->type);
o.WriteInt32((*s)->codec);
o.WriteInt32((unsigned char)(((*s)->enabled ? STREAM_FLAG_ENABLED : 0) | STREAM_FLAG_DTX));
o.WriteInt32((unsigned char)(((*s)->enabled ? ExtraStreamFlags::Flags::Enabled : 0) | ExtraStreamFlags::Flags::Dtx));
o.WriteInt16((*s)->frameDuration);
out.WriteInt16((int16_t)o.GetLength());
out.WriteBytes(o.GetBuffer(), o.GetLength());

115
controller/Constants.h Normal file
View File

@ -0,0 +1,115 @@
#pragma once
// Common macros
#define IS_MOBILE_NETWORK(x) (x == NET_TYPE_GPRS || x == NET_TYPE_EDGE || x == NET_TYPE_3G || x == NET_TYPE_HSPA || x == NET_TYPE_LTE || x == NET_TYPE_OTHER_MOBILE)
#define CHECK_ENDPOINT_PROTOCOL(endpointType, packetProtocol) ((endpointType != Endpoint::Type::TCP_RELAY && packetProtocol == NetworkProtocol::UDP) || (endpointType == Endpoint::Type::TCP_RELAY && packetProtocol == NetworkProtocol::TCP))
#define PAD4(x) (4 - (x + (x <= 253 ? 1 : 0)) % 4)
// Max recent packets
#define MAX_RECENT_PACKETS 128
// Packet types
#define PKT_INIT 1
#define PKT_INIT_ACK 2
#define PKT_STREAM_DATA 4
#define PKT_PING 6
#define PKT_PONG 7
#define PKT_NOP 14
#define PKT_STREAM_EC 17 // Deprecated
#define PKT_STREAM_DATA_X2 8 // Deprecated
#define PKT_STREAM_DATA_X3 9 // Deprecated
#define PKT_STREAM_STATE 3 // Deprecated, use extra
#define PKT_LAN_ENDPOINT 10 // Deprecated, use extra
#define PKT_NETWORK_CHANGED 11 // Deprecated, use extra
// #define PKT_UPDATE_STREAMS 5 // Not used anymore
// #define PKT_SWITCH_PREF_RELAY 12 // Not used anymore
// #define PKT_SWITCH_TO_P2P 13 // Not used anymore
// #define PKT_GROUP_CALL_KEY 15 // replaced with 'extra' in 2.1 (protocol v6)
// #define PKT_REQUEST_GROUP 16
// Stream data flags
#define STREAM_DATA_FLAG_LEN16 0x40
#define STREAM_DATA_FLAG_HAS_MORE_FLAGS 0x80 // Not used
// Since the data can't be larger than the MTU anyway,
// 5 top bits of data length are allocated for these flags
#define STREAM_DATA_XFLAG_KEYFRAME (1 << 15)
#define STREAM_DATA_XFLAG_FRAGMENTED (1 << 14)
#define STREAM_DATA_XFLAG_EXTRA_FEC (1 << 13)
// Extra packet flags
#define XPFLAG_HAS_EXTRA 1 // Signaling
#define XPFLAG_HAS_RECV_TS 2 // Video calls
// Old codec identifiers
#define CODEC_OPUS_OLD 1
// MTU
#define DEFAULT_MTU 1100
// Video flags
#define INIT_VIDEO_RES_NONE 0
#define INIT_VIDEO_RES_240 1
#define INIT_VIDEO_RES_360 2
#define INIT_VIDEO_RES_480 3
#define INIT_VIDEO_RES_720 4
#define INIT_VIDEO_RES_1080 5
#define INIT_VIDEO_RES_1440 6
#define INIT_VIDEO_RES_4K 7
#define VIDEO_FRAME_FLAG_KEYFRAME 1
#define VIDEO_ROTATION_MASK 3
#define VIDEO_ROTATION_0 0
#define VIDEO_ROTATION_90 1
#define VIDEO_ROTATION_180 2
#define VIDEO_ROTATION_270 3
#define FEC_SCHEME_XOR 1
#define FEC_SCHEME_CM256 2
// TLIDs of reflector signaling
#define TLID_DECRYPTED_AUDIO_BLOCK 0xDBF948C1
#define TLID_SIMPLE_AUDIO_BLOCK 0xCC0D0E76
#define TLID_UDP_REFLECTOR_PEER_INFO 0x27D9371C
#define TLID_UDP_REFLECTOR_PEER_INFO_IPV6 0x83fc73b1
#define TLID_UDP_REFLECTOR_SELF_INFO 0xc01572c7
#define TLID_UDP_REFLECTOR_REQUEST_PACKETS_INFO 0x1a06fc96
#define TLID_UDP_REFLECTOR_LAST_PACKETS_INFO 0x0e107305
#define TLID_VECTOR 0x1cb5c415
// Rating flags
#define NEED_RATE_FLAG_SHITTY_INTERNET_MODE 1
#define NEED_RATE_FLAG_UDP_NA 2
#define NEED_RATE_FLAG_UDP_BAD 4
#define NEED_RATE_FLAG_RECONNECTING 8
// Crypto stuff
#define SHA1_LENGTH 20
#define SHA256_LENGTH 32
#ifdef _MSC_VER
#define MSC_STACK_FALLBACK(a, b) (b)
#else
#define MSC_STACK_FALLBACK(a, b) (a)
#endif
// Legacy flags
/*flags:# voice_call_id:flags.2?int128 in_seq_no:flags.4?int out_seq_no:flags.4?int
* recent_received_mask:flags.5?int proto:flags.3?int extra:flags.1?string raw_data:flags.0?string*/
#define LEGACY_PFLAG_HAS_DATA 1
#define LEGACY_PFLAG_HAS_EXTRA 2
#define LEGACY_PFLAG_HAS_CALL_ID 4
#define LEGACY_PFLAG_HAS_PROTO 8
#define LEGACY_PFLAG_HAS_SEQ 16
#define LEGACY_PFLAG_HAS_RECENT_RECV 32
#define LEGACY_PFLAG_HAS_SENDER_TAG_HASH 64

View File

@ -5,134 +5,6 @@
#pragma once
#include <array>
// Common macros
#define IS_MOBILE_NETWORK(x) (x == NET_TYPE_GPRS || x == NET_TYPE_EDGE || x == NET_TYPE_3G || x == NET_TYPE_HSPA || x == NET_TYPE_LTE || x == NET_TYPE_OTHER_MOBILE)
#define CHECK_ENDPOINT_PROTOCOL(endpointType, packetProtocol) ((endpointType != Endpoint::Type::TCP_RELAY && packetProtocol == NetworkProtocol::UDP) || (endpointType == Endpoint::Type::TCP_RELAY && packetProtocol == NetworkProtocol::TCP))
#define PAD4(x) (4 - (x + (x <= 253 ? 1 : 0)) % 4)
// Protocol name/version
enum ProtocolVersions
{
PROTOCOL_OLD = 9,
PROTOCOL_RELIABLE = 10
};
#define PROTOCOL_NAME 0x50567247 // "GrVP" in little endian (reversed here)
#define PROTOCOL_VERSION 9
#define MIN_PROTOCOL_VERSION 3
// Max recent packets
#define MAX_RECENT_PACKETS 128
// Packet types
#define PKT_INIT 1
#define PKT_INIT_ACK 2
#define PKT_STREAM_DATA 4
#define PKT_PING 6
#define PKT_PONG 7
#define PKT_NOP 14
#define PKT_STREAM_EC 17 // Deprecated
#define PKT_STREAM_DATA_X2 8 // Deprecated
#define PKT_STREAM_DATA_X3 9 // Deprecated
#define PKT_STREAM_STATE 3 // Deprecated, use extra
#define PKT_LAN_ENDPOINT 10 // Deprecated, use extra
#define PKT_NETWORK_CHANGED 11 // Deprecated, use extra
// #define PKT_UPDATE_STREAMS 5 // Not used anymore
// #define PKT_SWITCH_PREF_RELAY 12 // Not used anymore
// #define PKT_SWITCH_TO_P2P 13 // Not used anymore
// #define PKT_GROUP_CALL_KEY 15 // replaced with 'extra' in 2.1 (protocol v6)
// #define PKT_REQUEST_GROUP 16
// Stream data flags
#define STREAM_DATA_FLAG_LEN16 0x40
#define STREAM_DATA_FLAG_HAS_MORE_FLAGS 0x80 // Not used
// Since the data can't be larger than the MTU anyway,
// 5 top bits of data length are allocated for these flags
#define STREAM_DATA_XFLAG_KEYFRAME (1 << 15)
#define STREAM_DATA_XFLAG_FRAGMENTED (1 << 14)
#define STREAM_DATA_XFLAG_EXTRA_FEC (1 << 13)
// Extra packet flags
#define XPFLAG_HAS_EXTRA 1 // Signaling
#define XPFLAG_HAS_RECV_TS 2 // Video calls
// For codec identifiers
#define FOURCC(a, b, c, d) ((uint32_t)d | ((uint32_t)c << 8) | ((uint32_t)b << 16) | ((uint32_t)a << 24))
#define PRINT_FOURCC(x) (char)(x >> 24), (char)(x >> 16), (char)(x >> 8), (char)x
#define CODEC_OPUS_OLD 1
// MTU
#define DEFAULT_MTU 1100
// Video flags
#define INIT_VIDEO_RES_NONE 0
#define INIT_VIDEO_RES_240 1
#define INIT_VIDEO_RES_360 2
#define INIT_VIDEO_RES_480 3
#define INIT_VIDEO_RES_720 4
#define INIT_VIDEO_RES_1080 5
#define INIT_VIDEO_RES_1440 6
#define INIT_VIDEO_RES_4K 7
#define VIDEO_FRAME_FLAG_KEYFRAME 1
#define VIDEO_ROTATION_MASK 3
#define VIDEO_ROTATION_0 0
#define VIDEO_ROTATION_90 1
#define VIDEO_ROTATION_180 2
#define VIDEO_ROTATION_270 3
#define FEC_SCHEME_XOR 1
#define FEC_SCHEME_CM256 2
// TLIDs of reflector signaling
#define TLID_DECRYPTED_AUDIO_BLOCK 0xDBF948C1
#define TLID_SIMPLE_AUDIO_BLOCK 0xCC0D0E76
#define TLID_UDP_REFLECTOR_PEER_INFO 0x27D9371C
#define TLID_UDP_REFLECTOR_PEER_INFO_IPV6 0x83fc73b1
#define TLID_UDP_REFLECTOR_SELF_INFO 0xc01572c7
#define TLID_UDP_REFLECTOR_REQUEST_PACKETS_INFO 0x1a06fc96
#define TLID_UDP_REFLECTOR_LAST_PACKETS_INFO 0x0e107305
#define TLID_VECTOR 0x1cb5c415
// Rating flags
#define NEED_RATE_FLAG_SHITTY_INTERNET_MODE 1
#define NEED_RATE_FLAG_UDP_NA 2
#define NEED_RATE_FLAG_UDP_BAD 4
#define NEED_RATE_FLAG_RECONNECTING 8
// Crypto stuff
#define SHA1_LENGTH 20
#define SHA256_LENGTH 32
#ifdef _MSC_VER
#define MSC_STACK_FALLBACK(a, b) (b)
#else
#define MSC_STACK_FALLBACK(a, b) (a)
#endif
// Legacy flags
/*flags:# voice_call_id:flags.2?int128 in_seq_no:flags.4?int out_seq_no:flags.4?int
* recent_received_mask:flags.5?int proto:flags.3?int extra:flags.1?string raw_data:flags.0?string*/
#define LEGACY_PFLAG_HAS_DATA 1
#define LEGACY_PFLAG_HAS_EXTRA 2
#define LEGACY_PFLAG_HAS_CALL_ID 4
#define LEGACY_PFLAG_HAS_PROTO 8
#define LEGACY_PFLAG_HAS_SEQ 16
#define LEGACY_PFLAG_HAS_RECENT_RECV 32
#define LEGACY_PFLAG_HAS_SENDER_TAG_HASH 64
#include "protocol/protocol/Extra.h"
#include "Constants.h"
#include "protocol/VersionInfo.h"
#include "protocol/protocol/Index.h"

View File

@ -37,8 +37,8 @@ VoIPController::VoIPController() : rawSendQueue(64)
shared_ptr<Stream> stm = make_shared<Stream>();
stm->id = 1;
stm->type = STREAM_TYPE_AUDIO;
stm->codec = CODEC_OPUS;
stm->type = StreamInfo::Type::Audio;
stm->codec = Codec::Opus;
stm->enabled = 1;
stm->frameDuration = 60;
stm->packetSender = std::make_unique<AudioPacketSender>(this, nullptr, stm);

View File

@ -209,7 +209,7 @@ string VoIPController::GetDebugString()
r += buffer;
}
double avgLate[3];
shared_ptr<Stream> stm = GetStreamByType(STREAM_TYPE_AUDIO, false);
shared_ptr<Stream> stm = GetStreamByType(StreamInfo::Type::Audio, false);
shared_ptr<JitterBuffer> jitterBuffer;
if (stm)
jitterBuffer = stm->jitterBuffer;
@ -249,7 +249,7 @@ string VoIPController::GetDebugString()
if (config.enableVideoSend)
{
shared_ptr<Stream> vstm = GetStreamByType(STREAM_TYPE_VIDEO, true);
shared_ptr<Stream> vstm = GetStreamByType(StreamInfo::Type::Video, true);
if (vstm && vstm->enabled && vstm->packetSender)
{
snprintf(buffer, sizeof(buffer), "\nVideo out: %ux%u '%c%c%c%c' %u kbit", vstm->width, vstm->height, PRINT_FOURCC(vstm->codec), dynamic_cast<video::VideoPacketSender *>(vstm->packetSender.get())->GetBitrate());
@ -267,7 +267,7 @@ string VoIPController::GetDebugString()
}
if (config.enableVideoReceive)
{
shared_ptr<Stream> vstm = GetStreamByType(STREAM_TYPE_VIDEO, false);
shared_ptr<Stream> vstm = GetStreamByType(StreamInfo::Type::Video, false);
if (vstm && vstm->enabled)
{
snprintf(buffer, sizeof(buffer), "\nVideo in: %ux%u '%c%c%c%c'", vstm->width, vstm->height, PRINT_FOURCC(vstm->codec));
@ -513,7 +513,7 @@ void VoIPController::SendGroupCallKey(unsigned char *key)
return;
}
didSendGroupCallKey = true;
SendExtra(*keyPtr, EXTRA_TYPE_GROUP_CALL_KEY);
SendExtra(*keyPtr, ExtraGroupCallKey::ID);
});
}
@ -537,7 +537,7 @@ void VoIPController::RequestCallUpgrade()
}
didSendUpgradeRequest = true;
Buffer empty(0);
SendExtra(empty, EXTRA_TYPE_REQUEST_GROUP);
SendExtra(empty, ExtraGroupCallUpgrade::ID);
});
}
@ -663,7 +663,7 @@ void VoIPController::SetAudioDataCallbacks(std::function<void(int16_t *, size_t)
{
audioInputDataCallback = input;
audioOutputDataCallback = output;
dynamic_cast<AudioPacketSender *>(GetStreamByType(STREAM_TYPE_AUDIO, true)->packetSender.get())->setAudioPreprocDataCallback(preproc);
dynamic_cast<AudioPacketSender *>(GetStreamByType(StreamInfo::Type::Audio, true)->packetSender.get())->setAudioPreprocDataCallback(preproc);
}
#endif

View File

@ -4,7 +4,7 @@ using namespace tgvoip;
using namespace std;
shared_ptr<VoIPController::Stream> VoIPController::GetStreamByType(StreamType type, bool outgoing)
shared_ptr<VoIPController::Stream> VoIPController::GetStreamByType(StreamInfo::Type type, bool outgoing)
{
for (shared_ptr<Stream> &ss : (outgoing ? outgoingStreams : incomingStreams))
{

View File

@ -8,7 +8,7 @@ using namespace std;
void VoIPController::InitializeAudio()
{
double t = GetCurrentTime();
shared_ptr<Stream> outgoingAudioStream = GetStreamByType(STREAM_TYPE_AUDIO, true);
shared_ptr<Stream> outgoingAudioStream = GetStreamByType(StreamInfo::Type::Audio, true);
LOGI("before create audio io");
audioIO = audio::AudioIO::Create(currentAudioInput, currentAudioOutput);
audioInput = audioIO->GetInput();
@ -102,7 +102,7 @@ void VoIPController::UpdateAudioOutputState()
bool areAnyAudioStreamsEnabled = false;
for (auto s = incomingStreams.begin(); s != incomingStreams.end(); ++s)
{
if ((*s)->type == STREAM_TYPE_AUDIO && (*s)->enabled)
if ((*s)->type == StreamInfo::Type::Audio && (*s)->enabled)
areAnyAudioStreamsEnabled = true;
}
if (audioOutput)

View File

@ -7,7 +7,7 @@ using namespace std;
void VoIPController::SetVideoSource(video::VideoSource *source)
{
shared_ptr<Stream> stm = GetStreamByType(STREAM_TYPE_VIDEO, true);
shared_ptr<Stream> stm = GetStreamByType(StreamInfo::Type::Video, true);
if (!stm)
{
LOGE("Can't set video source when there is no outgoing video stream");
@ -65,7 +65,7 @@ void VoIPController::ProcessIncomingVideoFrame(Buffer frame, uint32_t pts, bool
}
if (videoRenderer)
{
shared_ptr<Stream> stm = GetStreamByType(STREAM_TYPE_VIDEO, false);
shared_ptr<Stream> stm = GetStreamByType(StreamInfo::Type::Video, false);
size_t offset = 0;
if (keyframe)
{
@ -134,19 +134,19 @@ void VoIPController::SetupOutgoingVideoStream()
vector<uint32_t> myEncoders = video::VideoSource::GetAvailableEncoders();
shared_ptr<Stream> vstm = make_shared<Stream>();
vstm->id = 2;
vstm->type = STREAM_TYPE_VIDEO;
vstm->type = StreamInfo::Type::Video;
if (find(myEncoders.begin(), myEncoders.end(), CODEC_HEVC) != myEncoders.end() && find(peerVideoDecoders.begin(), peerVideoDecoders.end(), CODEC_HEVC) != peerVideoDecoders.end())
if (find(myEncoders.begin(), myEncoders.end(), Codec::Hevc) != myEncoders.end() && find(peerVideoDecoders.begin(), peerVideoDecoders.end(), Codec::Hevc) != peerVideoDecoders.end())
{
vstm->codec = CODEC_HEVC;
vstm->codec = Codec::Hevc;
}
else if (find(myEncoders.begin(), myEncoders.end(), CODEC_AVC) != myEncoders.end() && find(peerVideoDecoders.begin(), peerVideoDecoders.end(), CODEC_AVC) != peerVideoDecoders.end())
else if (find(myEncoders.begin(), myEncoders.end(), Codec::Avc) != myEncoders.end() && find(peerVideoDecoders.begin(), peerVideoDecoders.end(), Codec::Avc) != peerVideoDecoders.end())
{
vstm->codec = CODEC_AVC;
vstm->codec = Codec::Avc;
}
else if (find(myEncoders.begin(), myEncoders.end(), CODEC_VP8) != myEncoders.end() && find(peerVideoDecoders.begin(), peerVideoDecoders.end(), CODEC_VP8) != peerVideoDecoders.end())
else if (find(myEncoders.begin(), myEncoders.end(), Codec::Vp8) != myEncoders.end() && find(peerVideoDecoders.begin(), peerVideoDecoders.end(), Codec::Vp8) != peerVideoDecoders.end())
{
vstm->codec = CODEC_VP8;
vstm->codec = Codec::Vp8;
}
else
{

View File

@ -68,7 +68,7 @@ public:
uint8_t ipv6[16];
} addr;
private:
public:
NetworkAddress(){};
};

View File

@ -101,7 +101,7 @@ void VoIPController::SetNetworkType(int type)
SendPublicEndpointsRequest();
}
BufferOutputStream s(4);
s.WriteInt32(dataSavingMode ? INIT_FLAG_DATA_SAVING_ENABLED : 0);
s.WriteInt32(dataSavingMode ? ExtraInit::Flags::DataSavingEnabled : 0);
if (peerVersion < 6)
{
SendPacketReliably(PKT_NETWORK_CHANGED, s.GetBuffer(), s.GetLength(), 1, 20);
@ -109,7 +109,7 @@ void VoIPController::SetNetworkType(int type)
else
{
Buffer buf(move(s));
SendExtra(buf, EXTRA_TYPE_NETWORK_CHANGED);
SendExtra(buf, ExtraNetworkChanged::ID);
}
needReInitUdpProxy = true;
selectCanceller->CancelSelect();

View File

@ -121,13 +121,13 @@ void VoIPController::SendInit()
out.WriteInt32(MIN_PROTOCOL_VERSION);
uint32_t flags = 0;
if (config.enableCallUpgrade)
flags |= INIT_FLAG_GROUP_CALLS_SUPPORTED;
flags |= ExtraInit::Flags::GroupCallSupported;
if (config.enableVideoReceive)
flags |= INIT_FLAG_VIDEO_RECV_SUPPORTED;
flags |= ExtraInit::Flags::VideoRecvSupported;
if (config.enableVideoSend)
flags |= INIT_FLAG_VIDEO_SEND_SUPPORTED;
flags |= ExtraInit::Flags::VideoSendSupported;
if (dataSavingMode)
flags |= INIT_FLAG_DATA_SAVING_ENABLED;
flags |= ExtraInit::Flags::DataSavingEnabled;
out.WriteInt32(flags);
if (connectionMaxLayer < 74)
{
@ -136,14 +136,14 @@ void VoIPController::SendInit()
out.WriteByte(0);
out.WriteByte(0); // idk, stuff I guess
out.WriteByte(0);
out.WriteInt32(CODEC_OPUS);
out.WriteInt32(Codec::Opus);
out.WriteByte(0); // video codecs count (decode)
out.WriteByte(0); // video codecs count (encode)
}
else
{
out.WriteByte(1);
out.WriteInt32(CODEC_OPUS);
out.WriteInt32(Codec::Opus);
vector<uint32_t> decoders = config.enableVideoReceive ? video::VideoRenderer::GetAvailableDecoders() : vector<uint32_t>();
vector<uint32_t> encoders = config.enableVideoSend ? video::VideoSource::GetAvailableEncoders() : vector<uint32_t>();
out.WriteByte((unsigned char)decoders.size());
@ -513,13 +513,13 @@ void VoIPController::SendStreamFlags(Stream &stream)
s.WriteByte(stream.id);
uint32_t flags = 0;
if (stream.enabled)
flags |= STREAM_FLAG_ENABLED;
flags |= ExtraStreamFlags::Flags::Enabled;
if (stream.extraECEnabled)
flags |= STREAM_FLAG_EXTRA_EC;
flags |= ExtraStreamFlags::Flags::ExtraEC;
if (stream.paused)
flags |= STREAM_FLAG_PAUSED;
flags |= ExtraStreamFlags::Flags::Paused;
s.WriteInt32(flags);
LOGV("My stream state: id %u flags %u", (unsigned int)stream.id, (unsigned int)flags);
Buffer buf(move(s));
SendExtra(buf, EXTRA_TYPE_STREAM_FLAGS);
SendExtra(buf, ExtraStreamFlags::ID);
}

View File

@ -55,11 +55,6 @@ bool Packet::parse(const BufferInputStream &in, const VersionInfo &ver)
void Packet::serialize(BufferOutputStream &out, const VersionInfo &ver) const
{
if (!ver.isNew() || legacy)
{
return serializeLegacy(out, ver);
}
uint8_t shortStreamId = streamId > StreamId::Extended ? StreamId::Extended : streamId;
uint8_t flags = 0;
if (data.Length() > 0xFF || eFlags)

View File

@ -1,8 +1,8 @@
#pragma once
#include "../PrivateDefines.h"
#include "../../tools/Buffers.h"
#include "protocol/Interface.h"
#include "../PrivateDefines.h"
#include "protocol/Extra.h"
#include "protocol/Interface.h"
//#include "../net/PacketSender.h"
namespace tgvoip
@ -19,8 +19,12 @@ private:
bool parseLegacy(const BufferInputStream &in, const VersionInfo &ver);
bool parseLegacyLegacy(const BufferInputStream &in, unsigned char &type, uint32_t &ackId, uint32_t &pseq, uint32_t &acks, unsigned char &pflags, size_t &packetInnerLen, int peerVersion);
void serializeLegacy(BufferOutputStream &out, const VersionInfo &ver) const;
void serializeLegacyLegacy(BufferOutputStream &out, uint32_t pseq, uint32_t acks, unsigned char type, uint32_t length) const;
public:
void serializeLegacy(std::vector<std::pair<unsigned char *, size_t>> &out, const VersionInfo &ver, const int state, const unsigned char *callID);
private:
void writePacketHeaderLegacy(BufferOutputStream &out, const VersionInfo &ver, const uint32_t seq, const uint32_t ackSeq, const uint32_t ackMask, const unsigned char type, const std::vector<Wrapped<Extra>> &extras);
void writePacketHeaderLegacyLegacy(BufferOutputStream &out, const VersionInfo &ver, const uint32_t pseq, const uint32_t ackSeq, const uint32_t ackMask, const unsigned char type, const uint32_t length, const std::vector<Wrapped<Extra>> &extras, const int state, const unsigned char *callID);
public:
enum Flags : uint8_t
@ -64,11 +68,11 @@ public:
Mask<Wrapped<Bytes>> extraEC;
Array<Wrapped<Extra>> extraSignaling;
// Ugly backwards compatibility hack
std::vector<Packet> otherPackets;
// Ugly backwards compatibility hacks
std::vector<Packet> otherPackets; // parse
public:
operator bool() {
operator bool()
{
return data || extraEC || extraSignaling || seq;
}
};

View File

@ -1,5 +1,5 @@
#include "PacketStructs.h"
#include "../PrivateDefines.cpp"
#include "PacketStructs.h"
using namespace tgvoip;
@ -140,54 +140,177 @@ bool Packet::parseLegacy(const BufferInputStream &in, const VersionInfo &ver)
}
}
}
return true;
}
void Packet::serializeLegacy(BufferOutputStream &out, const VersionInfo &ver) const
void Packet::serializeLegacy(std::vector<std::pair<unsigned char *, size_t>> &outArray, const VersionInfo &ver, const int state, const unsigned char *callID)
{
uint8_t type = PKT_NOP;
for (const auto &extra : extraSignaling) {
}
if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92))
legacySeq = seq;
auto originalLegacySeq = legacySeq;
std::vector<Wrapped<Extra>> separatePackets;
std::vector<Wrapped<Extra>> allowedExtras;
std::partition_copy(
std::make_move_iterator(extraSignaling.begin()),
std::make_move_iterator(extraSignaling.end()),
std::back_inserter(separatePackets),
std::back_inserter(allowedExtras),
[peerVersion = ver.peerVersion](const Wrapped<Extra> &extra) { // Deliver as packet if
return extra.d->chooseType(peerVersion) != PKT_NOP;
});
for (const auto &extra : separatePackets)
{
out.WriteByte(pkt.type);
out.WriteInt32(manager.getLastRemoteSeq());
out.WriteInt32(pkt.seq);
out.WriteInt32(acks);
BufferOutputStream out(1500);
unsigned char flags = currentExtras.empty() ? 0 : XPFLAG_HAS_EXTRA;
shared_ptr<Stream> videoStream = GetStreamByType(STREAM_TYPE_VIDEO, false);
if (peerVersion >= 9 && videoStream && videoStream->enabled)
flags |= XPFLAG_HAS_RECV_TS;
if (peerVersion >= PROTOCOL_RELIABLE && manager.getTransportId() != 0xFF)
flags |= XPFLAG_HAS_TRANSPORT_ID;
out.WriteByte(flags);
if (!currentExtras.empty())
uint8_t type = extra.d->chooseType(ver.peerVersion);
if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92))
{
out.WriteByte(static_cast<unsigned char>(currentExtras.size()));
for (auto &x : currentExtras)
{
//LOGV("Writing extra into header: type %u, length %d", x.type, int(x.data.Length()));
assert(x.data.Length() <= 254);
out.WriteByte(static_cast<unsigned char>(x.data.Length() + 1));
out.WriteByte(x.type);
out.WriteBytes(*x.data, x.data.Length());
if (x.firstContainingSeq == 0)
x.firstContainingSeq = pkt.seq;
}
writePacketHeaderLegacy(out, ver, legacySeq, ackSeq, ackMask, type, allowedExtras);
out.Write(extra, ver);
}
if (peerVersion >= 9 && videoStream && videoStream->enabled)
else
{
out.WriteUInt32((lastRecvPacketTime - connectionInitTime) * 1000.0);
BufferOutputStream accumulator(1500);
accumulator.Write(extra, ver);
writePacketHeaderLegacyLegacy(out, ver, legacySeq, ackSeq, ackMask, type, accumulator.GetLength(), allowedExtras, state, callID);
out.WriteBytes(accumulator.GetBuffer(), accumulator.GetLength());
}
outArray.push_back(std::make_pair(out.GetBuffer(), out.GetLength()));
legacySeq++;
}
// Convert from mask to array
Array<Wrapped<Bytes>> extraECArray;
for (auto &ecPacket : extraEC.v)
{
extraECArray.v.push_back(std::move(ecPacket));
}
if (ver.peerVersion < 7 && extraEC)
{
BufferOutputStream out(1500);
if (!ver.isLegacyLegacy())
{
writePacketHeaderLegacy(out, ver, legacySeq, ackSeq, ackMask, PKT_STREAM_EC, allowedExtras);
}
out.WriteByte(streamId);
out.WriteUInt32(seq * 60);
out.Write(extraECArray, ver);
if (ver.isLegacyLegacy())
{
BufferOutputStream accumulator(1500);
writePacketHeaderLegacyLegacy(accumulator, ver, legacySeq, ackSeq, ackMask, PKT_STREAM_EC, out.GetLength(), allowedExtras, state, callID);
accumulator.WriteBytes(out.GetBuffer(), out.GetLength());
outArray.push_back(std::make_pair(accumulator.GetBuffer(), accumulator.GetLength()));
}
else
{
outArray.push_back(std::make_pair(out.GetBuffer(), out.GetLength()));
}
legacySeq++;
}
if (data)
{
BufferOutputStream out(1500);
if (!ver.isLegacyLegacy())
{
writePacketHeaderLegacy(out, ver, legacySeq, ackSeq, ackMask, PKT_STREAM_DATA, allowedExtras);
}
bool hasExtraFEC = ver.peerVersion >= 7 && extraEC;
uint8_t flags = static_cast<uint8_t>(data.Length() > 255 || hasExtraFEC ? STREAM_DATA_FLAG_LEN16 : 0);
out.WriteByte(flags | 1); // flags + streamID
if (flags & STREAM_DATA_FLAG_LEN16)
{
int16_t lenAndFlags = static_cast<int16_t>(data.Length());
if (hasExtraFEC)
lenAndFlags |= STREAM_DATA_XFLAG_EXTRA_FEC;
out.WriteInt16(lenAndFlags);
}
else
{
out.WriteByte(static_cast<uint8_t>(data.Length()));
}
out.WriteInt32(seq * 60);
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);
}
if (ver.isLegacyLegacy())
{
BufferOutputStream accumulator(1500);
writePacketHeaderLegacyLegacy(accumulator, ver, legacySeq, ackSeq, ackMask, PKT_STREAM_EC, out.GetLength(), allowedExtras, state, callID);
accumulator.WriteBytes(out.GetBuffer(), out.GetLength());
outArray.push_back(std::make_pair(accumulator.GetBuffer(), accumulator.GetLength()));
}
else
{
outArray.push_back(std::make_pair(out.GetBuffer(), out.GetLength()));
}
legacySeq++;
}
if (legacySeq == originalLegacySeq)
{
LOGW("Serializing NOP packet");
BufferOutputStream out(1500);
if (ver.peerVersion >= 8 || (!ver.peerVersion && ver.connectionMaxLayer >= 92))
{
writePacketHeaderLegacy(out, ver, legacySeq, ackSeq, ackMask, PKT_NOP, allowedExtras);
}
else
{
writePacketHeaderLegacyLegacy(out, ver, legacySeq, ackSeq, ackMask, PKT_NOP, 0, allowedExtras, state, callID);
}
outArray.push_back(std::make_pair(out.GetBuffer(), out.GetLength()));
}
}
void Packet::writePacketHeaderLegacy(BufferOutputStream &out, const VersionInfo &ver, const uint32_t seq, const uint32_t ackSeq, const uint32_t ackMask, const unsigned char type, const std::vector<Wrapped<Extra>> &extras)
{
out.WriteByte(type);
out.WriteInt32(ackSeq);
out.WriteInt32(seq);
out.WriteInt32(ackMask);
unsigned char flags = extras.empty() ? 0 : XPFLAG_HAS_EXTRA;
if (recvTS)
flags |= XPFLAG_HAS_RECV_TS;
out.WriteByte(flags);
if (!extras.empty())
{
out.WriteByte(static_cast<unsigned char>(extras.size()));
for (auto &x : extras)
{
LOGV("Writing extra into header: type %u", x.getID());
out.Write(x, ver);
}
}
if (recvTS)
{
out.WriteUInt32(recvTS);
}
}
bool Packet::parseLegacyLegacy(const BufferInputStream &in, unsigned char &type, uint32_t &ackId, uint32_t &pseq, uint32_t &acks, unsigned char &pflags, size_t &packetInnerLen, int peerVersion)
{
size_t packetInnerLen = 0;
uint32_t tlid = in.ReadUInt32();
if (tlid == TLID_DECRYPTED_AUDIO_BLOCK)
{
@ -271,18 +394,19 @@ bool Packet::parseLegacyLegacy(const BufferInputStream &in, unsigned char &type,
return true;
}
void Packet::serializeLegacyLegacy(BufferOutputStream &out, uint32_t pseq, uint32_t acks, unsigned char type, uint32_t length) const
void Packet::writePacketHeaderLegacyLegacy(BufferOutputStream &out, const VersionInfo &ver, const uint32_t pseq, const uint32_t ackSeq, const uint32_t ackMask, const unsigned char type, const uint32_t length, const std::vector<Wrapped<Extra>> &extras, const int state, const unsigned char *callID)
{
out.WriteInt32(state == STATE_WAIT_INIT || state == STATE_WAIT_INIT_ACK ? TLID_DECRYPTED_AUDIO_BLOCK : TLID_SIMPLE_AUDIO_BLOCK);
int64_t randomID;
VoIPController::crypto.rand_bytes((uint8_t *)&randomID, 8);
out.WriteInt64(randomID);
unsigned char randBytes[7];
VoIPController::crypto.rand_bytes(randBytes, 7);
out.WriteByte(7);
out.WriteBytes(randBytes, 7);
if (state == STATE_WAIT_INIT || state == STATE_WAIT_INIT_ACK)
{
out.WriteInt32(TLID_DECRYPTED_AUDIO_BLOCK);
int64_t randomID;
crypto.rand_bytes((uint8_t *)&randomID, 8);
out.WriteInt64(randomID);
unsigned char randBytes[7];
crypto.rand_bytes(randBytes, 7);
out.WriteByte(7);
out.WriteBytes(randBytes, 7);
uint32_t pflags = LEGACY_PFLAG_HAS_RECENT_RECV | LEGACY_PFLAG_HAS_SEQ;
if (length > 0)
pflags |= LEGACY_PFLAG_HAS_DATA;
@ -297,9 +421,9 @@ void Packet::serializeLegacyLegacy(BufferOutputStream &out, uint32_t pseq, uint3
{
out.WriteBytes(callID, 16);
}
out.WriteInt32(packetManager.getLastRemoteSeq());
out.WriteInt32(ackSeq);
out.WriteInt32(pseq);
out.WriteInt32(acks);
out.WriteInt32(ackMask);
if (pflags & LEGACY_PFLAG_HAS_PROTO)
{
out.WriteInt32(PROTOCOL_NAME);
@ -321,14 +445,6 @@ void Packet::serializeLegacyLegacy(BufferOutputStream &out, uint32_t pseq, uint3
}
else
{
out.WriteInt32(TLID_SIMPLE_AUDIO_BLOCK);
int64_t randomID;
crypto.rand_bytes((uint8_t *)&randomID, 8);
out.WriteInt64(randomID);
unsigned char randBytes[7];
crypto.rand_bytes(randBytes, 7);
out.WriteByte(7);
out.WriteBytes(randBytes, 7);
uint32_t lenWithHeader = length + 13;
if (lenWithHeader > 0)
{
@ -345,28 +461,23 @@ void Packet::serializeLegacyLegacy(BufferOutputStream &out, uint32_t pseq, uint3
}
}
out.WriteByte(type);
out.WriteInt32(packetManager.getLastRemoteSeq());
out.WriteInt32(ackSeq);
out.WriteInt32(pseq);
out.WriteInt32(acks);
if (peerVersion >= 6)
out.WriteInt32(ackMask);
if (ver.peerVersion >= 6)
{
if (currentExtras.empty())
if (extras.empty())
{
out.WriteByte(0);
}
else
{
out.WriteByte(XPFLAG_HAS_EXTRA);
out.WriteByte(static_cast<unsigned char>(currentExtras.size()));
for (vector<UnacknowledgedExtraData>::iterator x = currentExtras.begin(); x != currentExtras.end(); ++x)
out.WriteByte(static_cast<unsigned char>(extras.size()));
for (auto &x : extras)
{
LOGV("Writing extra into header: type %u, length %d", x->type, int(x->data.Length()));
assert(x->data.Length() <= 254);
out.WriteByte(static_cast<unsigned char>(x->data.Length() + 1));
out.WriteByte(x->type);
out.WriteBytes(*x->data, x->data.Length());
if (x->firstContainingSeq == 0)
x->firstContainingSeq = pseq;
LOGV("Writing extra into header: type %u", x.getID());
out.Write(x, ver);
}
}
}

View File

@ -286,21 +286,21 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
uint32_t flags = in.ReadUInt32();
if (!receivedInit)
{
if (flags & INIT_FLAG_DATA_SAVING_ENABLED)
if (flags & ExtraInit::Flags::DataSavingEnabled)
{
dataSavingRequestedByPeer = true;
UpdateDataSavingState();
UpdateAudioBitrateLimit();
}
if (flags & INIT_FLAG_GROUP_CALLS_SUPPORTED)
if (flags & ExtraInit::Flags::GroupCallSupported)
{
peerCapabilities |= TGVOIP_PEER_CAP_GROUP_CALLS;
}
if (flags & INIT_FLAG_VIDEO_RECV_SUPPORTED)
if (flags & ExtraInit::Flags::VideoRecvSupported)
{
peerCapabilities |= TGVOIP_PEER_CAP_VIDEO_DISPLAY;
}
if (flags & INIT_FLAG_VIDEO_SEND_SUPPORTED)
if (flags & ExtraInit::Flags::VideoSendSupported)
{
peerCapabilities |= TGVOIP_PEER_CAP_VIDEO_CAPTURE;
}
@ -314,10 +314,10 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
else
in.ReadInt32();
}
if (!receivedInit && ((flags & INIT_FLAG_VIDEO_SEND_SUPPORTED && config.enableVideoReceive) || (flags & INIT_FLAG_VIDEO_RECV_SUPPORTED && config.enableVideoSend)))
if (!receivedInit && ((flags & ExtraInit::Flags::VideoSendSupported && config.enableVideoReceive) || (flags & ExtraInit::Flags::VideoRecvSupported && config.enableVideoSend)))
{
LOGD("Peer video decoders:");
unsigned int numSupportedVideoDecoders = in.ReadByte();
uint8_t numSupportedVideoDecoders = in.ReadByte();
for (auto i = 0; i < numSupportedVideoDecoders; i++)
{
uint32_t id = in.ReadUInt32();
@ -341,7 +341,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
out.WriteByte(stream->id);
out.WriteByte(stream->type);
if (peerVersion < 5)
out.WriteByte((unsigned char)(stream->codec == CODEC_OPUS ? CODEC_OPUS_OLD : 0));
out.WriteByte((unsigned char)(stream->codec == Codec::Opus ? CODEC_OPUS_OLD : 0));
else
out.WriteInt32(stream->codec);
out.WriteInt16(stream->frameDuration);
@ -411,12 +411,12 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
{
shared_ptr<Stream> stm = make_shared<Stream>();
stm->id = in.ReadByte();
stm->type = static_cast<StreamType>(in.ReadByte());
stm->type = static_cast<StreamInfo::Type>(in.ReadByte());
if (peerVersion < 5)
{
unsigned char codec = in.ReadByte();
if (codec == CODEC_OPUS_OLD)
stm->codec = CODEC_OPUS;
stm->codec = Codec::Opus;
}
else
{
@ -425,12 +425,12 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
in.ReadInt16();
stm->frameDuration = 60;
stm->enabled = in.ReadByte() == 1;
if (stm->type == STREAM_TYPE_VIDEO && peerVersion < 9)
if (stm->type == StreamInfo::Type::Video && peerVersion < 9)
{
LOGV("Skipping video stream for old protocol version");
continue;
}
if (stm->type == STREAM_TYPE_AUDIO)
if (stm->type == StreamInfo::Type::Audio)
{
stm->jitterBuffer = make_shared<JitterBuffer>(stm->frameDuration);
if (stm->frameDuration > 50)
@ -441,7 +441,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
stm->jitterBuffer->SetMinPacketCount(ServerConfig::GetSharedInstance()->GetUInt("jitter_initial_delay_20", 6));
stm->decoder = nullptr;
}
else if (stm->type == STREAM_TYPE_VIDEO)
else if (stm->type == StreamInfo::Type::Video)
{
if (!stm->packetReassembler)
{
@ -455,7 +455,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
continue;
}
incomingStreams.push_back(stm);
if (stm->type == STREAM_TYPE_AUDIO && !incomingAudioStream)
if (stm->type == StreamInfo::Type::Audio && !incomingAudioStream)
incomingAudioStream = stm;
}
if (!incomingAudioStream)
@ -556,7 +556,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
break;
}
}
if (stm && stm->type == STREAM_TYPE_AUDIO)
if (stm && stm->type == StreamInfo::Type::Audio)
{
if (stm->jitterBuffer)
{
@ -582,7 +582,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
}
}
}
else if (stm && stm->type == STREAM_TYPE_VIDEO)
else if (stm && stm->type == StreamInfo::Type::Video)
{
if (stm->packetReassembler)
{
@ -702,7 +702,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
if (peerVersion >= 2)
{
uint32_t flags = in.ReadUInt32();
dataSavingRequestedByPeer = (flags & INIT_FLAG_DATA_SAVING_ENABLED) == INIT_FLAG_DATA_SAVING_ENABLED;
dataSavingRequestedByPeer = flags & ExtraInit::Flags::DataSavingEnabled;
UpdateDataSavingState();
UpdateAudioBitrateLimit();
ResetEndpointPingStats();
@ -741,7 +741,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
LOGW("Received FEC packet for unknown stream %u", streamID);
return;
}
if (stm->type != STREAM_TYPE_VIDEO)
if (stm->type != StreamInfo::Type::Video)
{
LOGW("Received FEC packet for non-video stream %u", streamID);
return;
@ -777,7 +777,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
}
LOGE("ProcessExtraData");
lastReceivedExtrasByType[type] = hash;
if (type == EXTRA_TYPE_STREAM_FLAGS)
if (type == ExtraStreamFlags::ID)
{
unsigned char id = in.ReadByte();
uint32_t flags = in.ReadUInt32();
@ -788,9 +788,9 @@ void VoIPController::ProcessExtraData(Buffer &data)
{
bool prevEnabled = s->enabled;
bool prevPaused = s->paused;
s->enabled = (flags & STREAM_FLAG_ENABLED) == STREAM_FLAG_ENABLED;
s->paused = (flags & STREAM_FLAG_PAUSED) == STREAM_FLAG_PAUSED;
if (flags & STREAM_FLAG_EXTRA_EC)
s->enabled = flags & ExtraStreamFlags::Flags::Enabled;
s->paused = flags & ExtraStreamFlags::Flags::Paused;
if (flags & ExtraStreamFlags::Flags::ExtraEC)
{
if (!s->extraECEnabled)
{
@ -808,16 +808,16 @@ void VoIPController::ProcessExtraData(Buffer &data)
s->jitterBuffer->SetMinPacketCount(2);
}
}
if (prevEnabled != s->enabled && s->type == STREAM_TYPE_VIDEO && videoRenderer)
if (prevEnabled != s->enabled && s->type == StreamInfo::Type::Video && videoRenderer)
videoRenderer->SetStreamEnabled(s->enabled);
if (prevPaused != s->paused && s->type == STREAM_TYPE_VIDEO && videoRenderer)
if (prevPaused != s->paused && s->type == StreamInfo::Type::Video && videoRenderer)
videoRenderer->SetStreamPaused(s->paused);
UpdateAudioOutputState();
break;
}
}
}
else if (type == EXTRA_TYPE_STREAM_CSD)
else if (type == ExtraStreamCsd::ID)
{
LOGI("Received codec specific data");
unsigned char streamID = in.ReadByte();
@ -841,7 +841,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
}
}
}
else if (type == EXTRA_TYPE_LAN_ENDPOINT)
else if (type == ExtraLanEndpoint::ID)
{
if (!allowP2p)
return;
@ -857,7 +857,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
MutexGuard m(endpointsMutex);
endpoints[lanID] = lan;
}
else if (type == EXTRA_TYPE_NETWORK_CHANGED)
else if (type == ExtraNetworkChanged::ID)
{
LOGI("Peer network changed");
wasNetworkHandover = true;
@ -867,12 +867,12 @@ void VoIPController::ProcessExtraData(Buffer &data)
if (allowP2p)
SendPublicEndpointsRequest();
uint32_t flags = in.ReadUInt32();
dataSavingRequestedByPeer = (flags & INIT_FLAG_DATA_SAVING_ENABLED) == INIT_FLAG_DATA_SAVING_ENABLED;
dataSavingRequestedByPeer = flags & ExtraInit::Flags::DataSavingEnabled;
UpdateDataSavingState();
UpdateAudioBitrateLimit();
ResetEndpointPingStats();
}
else if (type == EXTRA_TYPE_GROUP_CALL_KEY)
else if (type == ExtraGroupCallKey::ID)
{
if (!didReceiveGroupCallKey && !didSendGroupCallKey)
{
@ -885,7 +885,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
didReceiveGroupCallKey = true;
}
}
else if (type == EXTRA_TYPE_REQUEST_GROUP)
else if (type == ExtraGroupCallUpgrade::ID)
{
if (!didInvokeUpgradeCallback)
{
@ -896,7 +896,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
didInvokeUpgradeCallback = true;
}
}
else if (type == EXTRA_TYPE_IPV6_ENDPOINT)
else if (type == ExtraIpv6Endpoint::ID)
{
if (!allowP2p)
return;
@ -920,7 +920,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
void VoIPController::ProcessAcknowledgedOutgoingExtra(UnacknowledgedExtraData &extra)
{
if (extra.type == EXTRA_TYPE_GROUP_CALL_KEY)
if (extra.type == ExtraGroupCallKey::ID)
{
if (!didReceiveGroupCallKeyAck)
{
@ -947,13 +947,10 @@ uint8_t VoIPController::WritePacketHeader(PendingOutgoingPacket &pkt, BufferOutp
unsigned char flags = currentExtras.empty() ? 0 : XPFLAG_HAS_EXTRA;
shared_ptr<Stream> videoStream = GetStreamByType(STREAM_TYPE_VIDEO, false);
shared_ptr<Stream> videoStream = GetStreamByType(StreamInfo::Type::Video, false);
if (peerVersion >= 9 && videoStream && videoStream->enabled)
flags |= XPFLAG_HAS_RECV_TS;
if (peerVersion >= PROTOCOL_RELIABLE && manager.getTransportId() != 0xFF)
flags |= XPFLAG_HAS_TRANSPORT_ID;
s.WriteByte(flags);
if (!currentExtras.empty())

View File

@ -51,7 +51,7 @@ bool VoIPController::parseRelayPacket(const BufferInputStream &in, Endpoint &src
o.WriteBytes(myIP, 16);
o.WriteInt16(udpSocket->GetLocalPort());
Buffer b(move(o));
SendExtra(b, EXTRA_TYPE_IPV6_ENDPOINT);
SendExtra(b, ExtraIpv6Endpoint::ID);
}
}
}
@ -103,7 +103,7 @@ bool VoIPController::parseRelayPacket(const BufferInputStream &in, Endpoint &src
else
{
Buffer buf(move(pkt));
SendExtra(buf, EXTRA_TYPE_LAN_ENDPOINT);
SendExtra(buf, ExtraLanEndpoint::ID);
}
}
waitingForRelayPeerInfo = false;

View File

@ -196,7 +196,7 @@ void VoIPController::UpdateCongestion()
double avgSendLossCount = sendLossCountHistory.Average() / packetCountHistory.Average();
LOGE("avg send loss: %.3f%%", avgSendLossCount*100);
AudioPacketSender *sender = dynamic_cast<AudioPacketSender *>(GetStreamByType(STREAM_TYPE_AUDIO, true)->packetSender.get());
AudioPacketSender *sender = dynamic_cast<AudioPacketSender *>(GetStreamByType(StreamInfo::Type::Audio, true)->packetSender.get());
//avgSendLossCount = sender->setPacketLoss(avgSendLossCount * 100.0) / 100.0;
sender->setPacketLoss(avgSendLossCount * 100.0);
if (avgSendLossCount > packetLossToEnableExtraEC && networkType != NET_TYPE_GPRS && networkType != NET_TYPE_EDGE)
@ -207,7 +207,7 @@ void VoIPController::UpdateCongestion()
sender->setShittyInternetMode(true);
for (shared_ptr<Stream> &s : outgoingStreams)
{
if (s->type == STREAM_TYPE_AUDIO)
if (s->type == StreamInfo::Type::Audio)
{
s->extraECEnabled = true;
SendStreamFlags(*s);
@ -248,7 +248,7 @@ void VoIPController::UpdateCongestion()
sender->setShittyInternetMode(false);
for (shared_ptr<Stream> &s : outgoingStreams)
{
if (s->type == STREAM_TYPE_AUDIO)
if (s->type == StreamInfo::Type::Audio)
{
s->extraECEnabled = false;
SendStreamFlags(*s);
@ -277,7 +277,7 @@ void VoIPController::UpdateAudioBitrate()
}
int act = conctl.GetBandwidthControlAction();
if (dynamic_cast<AudioPacketSender *>(GetStreamByType(STREAM_TYPE_AUDIO, true)->packetSender.get())->getShittyInternetMode())
if (dynamic_cast<AudioPacketSender *>(GetStreamByType(StreamInfo::Type::Audio, true)->packetSender.get())->getShittyInternetMode())
{
encoder->SetBitrate(8000);
}
@ -328,7 +328,7 @@ void VoIPController::UpdateAudioBitrate()
UpdateDataSavingState();
UpdateAudioBitrateLimit();
BufferOutputStream s(4);
s.WriteInt32(dataSavingMode ? INIT_FLAG_DATA_SAVING_ENABLED : 0);
s.WriteInt32(dataSavingMode ? ExtraInit::Flags::DataSavingEnabled : 0);
if (peerVersion < 6)
{
SendPacketReliably(PKT_NETWORK_CHANGED, s.GetBuffer(), s.GetLength(), 1, 20);
@ -336,7 +336,7 @@ void VoIPController::UpdateAudioBitrate()
else
{
Buffer buf(move(s));
SendExtra(buf, EXTRA_TYPE_NETWORK_CHANGED);
SendExtra(buf, ExtraNetworkChanged::ID);
}
lastRecvPacketTime = time;
}

View File

@ -0,0 +1,31 @@
#include <cstdint>
// Protocol name/version
enum ProtocolVersions : int
{
PROTOCOL_OLD = 9,
PROTOCOL_RELIABLE = 10
};
#define PROTOCOL_NAME 0x50567247 // "GrVP" in little endian (reversed here)
#define PROTOCOL_VERSION 9
#define MIN_PROTOCOL_VERSION 3
namespace tgvoip
{
struct VersionInfo
{
VersionInfo(int _peerVersion, int32_t _connectionMaxLayer) : peerVersion(_peerVersion), connectionMaxLayer(_connectionMaxLayer){};
const int peerVersion = 0;
const int32_t connectionMaxLayer = 0;
inline bool isNew() const
{
return peerVersion >= PROTOCOL_RELIABLE || connectionMaxLayer >= 110;
}
inline bool isLegacyLegacy() const
{
return !(peerVersion >= 8 || (!peerVersion && connectionMaxLayer >= 92));
}
};
} // namespace tgvoip

View File

@ -1,4 +1,5 @@
#include "Extra.h"
#include "../../PrivateDefines.h"
using namespace tgvoip;
@ -78,6 +79,33 @@ std::shared_ptr<Extra> Extra::chooseFromType(uint8_t type)
}
return nullptr;
}
uint8_t Extra::chooseType(int peerVersion) const
{
switch (getID())
{
case ExtraInit::ID:
return PKT_INIT;
case ExtraInitAck::ID:
return PKT_INIT_ACK;
case ExtraPing::ID:
return PKT_PING;
case ExtraPong::ID:
return PKT_PONG;
}
if (peerVersion < 6)
{
switch (getID())
{
case ExtraLanEndpoint::ID:
return PKT_LAN_ENDPOINT;
case ExtraNetworkChanged::ID:
return PKT_NETWORK_CHANGED;
case ExtraStreamFlags::ID:
return PKT_STREAM_STATE;
}
}
return PKT_NOP;
}
bool StreamInfo::parse(const BufferInputStream &in, const VersionInfo &ver)
{
@ -192,12 +220,12 @@ void ExtraInit::serialize(BufferOutputStream &out, const VersionInfo &ver) const
{
out.WriteByte(2); // audio codecs count, for some reason two codecs required
out.WriteByte(CODEC_OPUS_OLD);
out.WriteByte(0); // second useless codec
out.WriteByte(0); // what is this
out.WriteByte(0); // what is this
out.WriteInt32(CODEC_OPUS); // WHAT IS THIS
out.WriteByte(0); // video codecs count (decode)
out.WriteByte(0); // video codecs count (encode)
out.WriteByte(0); // second useless codec
out.WriteByte(0); // what is this
out.WriteByte(0); // what is this
out.WriteInt32(Codec::Opus); // WHAT IS THIS
out.WriteByte(0); // video codecs count (decode)
out.WriteByte(0); // video codecs count (encode)
}
else
{

View File

@ -1,14 +1,19 @@
#pragma once
#include "Interface.h"
#include "../../../tools/Buffers.h"
#include "../../PrivateDefines.h"
#include "../../net/NetworkSocket.h"
#include "Interface.h"
#define FOURCC(a, b, c, d) ((uint32_t)d | ((uint32_t)c << 8) | ((uint32_t)b << 16) | ((uint32_t)a << 24))
#define PRINT_FOURCC(x) (char)(x >> 24), (char)(x >> 16), (char)(x >> 8), (char)x
namespace tgvoip
{
struct VersionInfo;
struct Extra : public Serializable, MultiChoice<Extra>
{
static std::shared_ptr<Extra> choose(const BufferInputStream &in, const VersionInfo &ver);
static std::shared_ptr<Extra> chooseFromType(uint8_t type);
uint8_t chooseType(int peerVersion) const;
};
struct Codec : public Serializable, SingleChoice<Codec>
@ -17,14 +22,16 @@ public:
bool parse(const BufferInputStream &in, const VersionInfo &ver) override;
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override;
static const uint32_t Opus = FOURCC('O', 'P', 'U', 'S');
static const uint32_t Avc = FOURCC('A', 'V', 'C', ' ');
static const uint32_t Hevc = FOURCC('H', 'E', 'V', 'C');
static const uint32_t Vp8 = FOURCC('V', 'P', '8', '0');
static const uint32_t Vp9 = FOURCC('V', 'P', '9', '0');
static const uint32_t Av1 = FOURCC('A', 'V', '0', '1');
enum : uint32_t
{
Opus = FOURCC('O', 'P', 'U', 'S'),
Avc = FOURCC('A', 'V', 'C', ' '),
Hevc = FOURCC('H', 'E', 'V', 'C'),
Vp8 = FOURCC('V', 'P', '8', '0'),
Vp9 = FOURCC('V', 'P', '9', '0'),
Av1 = FOURCC('A', 'V', '0', '1')
};
uint32_t codec = 0;
};
@ -64,6 +71,10 @@ public:
uint8_t streamId;
uint8_t flags = 0;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 1;
};
@ -79,32 +90,13 @@ public:
Array<Bytes> data;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 2;
};
struct ExtraLanEndpoint : public Extra
{
public:
virtual bool parse(const BufferInputStream &in, const VersionInfo &ver);
virtual void serialize(BufferOutputStream &out, const VersionInfo &ver);
NetworkAddress address;
uint16_t port = 0;
static const uint8_t ID = 3;
};
struct ExtraIpv6Endpoint : public Extra
{
bool parse(const BufferInputStream &in, const VersionInfo &ver) override;
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override;
NetworkAddress address;
uint16_t port = 0;
static const uint8_t ID = 7;
};
struct ExtraNetworkChanged : public Extra
{
bool parse(const BufferInputStream &in, const VersionInfo &ver) override;
@ -118,9 +110,44 @@ struct ExtraNetworkChanged : public Extra
uint8_t streamId = 0;
uint8_t flags = 0;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 4;
};
struct ExtraLanEndpoint : public Extra
{
public:
bool parse(const BufferInputStream &in, const VersionInfo &ver) override;
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override;
NetworkAddress address;
uint16_t port = 0;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 3;
};
struct ExtraIpv6Endpoint : public Extra
{
bool parse(const BufferInputStream &in, const VersionInfo &ver) override;
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override;
NetworkAddress address;
uint16_t port = 0;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 7;
};
struct ExtraGroupCallKey : public Extra
{
bool parse(const BufferInputStream &in, const VersionInfo &ver) override;
@ -128,6 +155,10 @@ struct ExtraGroupCallKey : public Extra
std::array<uint8_t, 256> key;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 5;
};
@ -136,6 +167,10 @@ struct ExtraGroupCallUpgrade : public Extra
bool parse(const BufferInputStream &in, const VersionInfo &ver) override { return true; };
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override{};
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 6;
};
@ -161,6 +196,10 @@ struct ExtraInit : public Extra
Array<UInt32> decoders;
uint8_t maxResolution;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 8;
};
@ -174,7 +213,11 @@ struct ExtraInitAck : public Extra
Array<StreamInfo> streams;
static const uint8_t ID = 8;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 9;
};
struct ExtraPing : public Extra
@ -182,7 +225,11 @@ struct ExtraPing : public Extra
bool parse(const BufferInputStream &in, const VersionInfo &ver) override { return true; };
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override{};
static const uint8_t ID = 9;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 10;
};
struct ExtraPong : public Extra
{
@ -191,6 +238,10 @@ struct ExtraPong : public Extra
uint32_t seq = 0;
static const uint8_t ID = 9;
uint8_t getID() const
{
return ID;
}
static const uint8_t ID = 11;
};
} // namespace tgvoip

View File

@ -0,0 +1,2 @@
#include "Extra.h"
#include "Interface.h"

View File

@ -1,21 +1,11 @@
#pragma once
#include "../../../tools/Buffers.h"
#include <memory>
#include <type_traits>
namespace tgvoip
{
struct VersionInfo
{
VersionInfo(int _peerVersion, int32_t _connectionMaxLayer) : peerVersion(_peerVersion), connectionMaxLayer(_connectionMaxLayer){};
const int peerVersion = 0;
const int32_t connectionMaxLayer = 0;
inline bool isNew() const
{
return peerVersion >= PROTOCOL_RELIABLE || connectionMaxLayer >= 110;
}
};
struct VersionInfo;
template <typename T>
struct SingleChoice
@ -24,12 +14,53 @@ struct SingleChoice
{
return std::make_shared<T>();
}
uint8_t getID() const
{
return 0;
}
static const uint8_t ID = 0;
};
template <typename T>
struct MultiChoice
{
static std::shared_ptr<T> choose(const BufferInputStream &in, const VersionInfo &ver);
private:
static std::shared_ptr<T> __forceChoice(const BufferInputStream &in, const VersionInfo &ver)
{
return T::choose(in, ver);
}
public:
virtual uint8_t getID() const = 0;
};
template <class T, class = void>
struct has_flags : std::false_type
{
};
template <class T>
struct has_flags<T, std::void_t<typename T::Flags>> : std::true_type
{
};
struct Empty
{
enum Flags : uint8_t
{
};
};
template <typename T>
struct Constructor // : public T
{
uint8_t getID() const
{
return T::ID;
}
using Flags = typename std::conditional<tgvoip::has_flags<T>::value, T, Empty>::type::Flags;
};
struct Serializable
@ -49,7 +80,7 @@ struct Mask : public Serializable, SingleChoice<Mask<T>>
{
return false;
}
for (auto i = 0; i < sizeof(mask); i++)
for (uint8_t i = 0; i < 8; i++)
{
if (!(i & (1 << i)))
continue;
@ -62,7 +93,7 @@ struct Mask : public Serializable, SingleChoice<Mask<T>>
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override
{
uint8_t mask = 0;
for (auto i = 0; i < sizeof(mask); i++)
for (uint8_t i = 0; i < 8; i++)
{
if (v[i])
{
@ -72,24 +103,24 @@ struct Mask : public Serializable, SingleChoice<Mask<T>>
out.WriteByte(mask);
for (const auto &data : v)
{
out.Write(v, data);
out.Write(data, ver);
}
}
typename std::array<T, 8>::iterator begin()
auto begin() noexcept
{
return v.begin();
}
typename std::array<T, 8>::iterator end()
auto end() noexcept
{
return v.end();
}
typename std::array<T, 8>::const_iterator cbegin()
const auto begin() const noexcept
{
return v.cbegin();
return v.begin();
}
typename std::array<T, 8>::const_iterator cend()
const auto end() const noexcept
{
return v.cend();
return v.end();
}
operator bool() const
{
@ -133,21 +164,21 @@ struct Array : public Serializable, SingleChoice<Array<T>>
data.serialize(out, ver);
}
}
typename std::vector<T>::iterator begin()
auto begin() noexcept
{
return v.begin();
}
typename std::vector<T>::iterator end()
auto end() noexcept
{
return v.end();
}
typename std::vector<T>::const_iterator cbegin()
const auto begin() const noexcept
{
return v.cbegin();
return v.begin();
}
typename std::vector<T>::const_iterator cend()
const auto end() const noexcept
{
return v.cend();
return v.end();
}
operator bool() const
{
@ -169,7 +200,7 @@ struct Wrapped : public Serializable, SingleChoice<Wrapped<T>>
if (!in.TryRead(len))
return false;
d = T::choose(in, ver);
return d->parse(in.GetPartBuffer(len));
return d->parse(in.GetPartBuffer(len), ver);
}
void serialize(BufferOutputStream &out, const VersionInfo &ver) const override
{
@ -185,7 +216,39 @@ struct Wrapped : public Serializable, SingleChoice<Wrapped<T>>
{
return d && *d;
}
uint8_t getID() const
{
return d->getID();
}
template <typename X>
X &get()
{
return *dynamic_cast<X>(d.get());
}
template <typename X>
const X &get() const
{
return *dynamic_cast<X>(d.get());
}
template <typename X>
operator X &()
{
return *dynamic_cast<X>(d.get());
}
template <typename X>
operator const X &() const
{
return *dynamic_cast<X>(d.get());
}
std::shared_ptr<T> d;
static const uint8_t ID = T::ID;
};
struct Bytes : public Serializable,
@ -206,6 +269,7 @@ struct Bytes : public Serializable,
}
Buffer data;
};
struct UInt32 : public Serializable, SingleChoice<UInt32>
{
bool parse(const BufferInputStream &in, const VersionInfo &ver)
@ -218,4 +282,12 @@ struct UInt32 : public Serializable, SingleChoice<UInt32>
}
uint32_t data;
};
namespace Template
{
template <class T>
struct Constructor : public T, tgvoip::Constructor<T>
{
};
}; // namespace Template
} // namespace tgvoip

View File

@ -9,7 +9,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdexcept>
#include <array>
#include <limits>

View File

@ -7,6 +7,7 @@
#pragma once
#include <numeric>
#include <algorithm>
#include <assert.h>
#define TGVOIP_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
@ -44,9 +45,9 @@ public:
{
AVG_T avg = static_cast<AVG_T>(0);
int nonZeroCount = 0;
for (T &i : data)
for (const T &i : data)
{
if (i != 0)
if (i)
{
nonZeroCount++;
avg += i;

View File

@ -329,7 +329,7 @@ int VideoPacketSender::GetVideoResolutionForCurrentBitrate()
if (VoIPController::GetCurrentTime() - sourceChangeTime > 10.0)
{
// TODO: probably move this to server config
if (stream->codec == CODEC_AVC || stream->codec == CODEC_VP8)
if (stream->codec == Codec::Avc || stream->codec == Codec::Vp8)
{
if (currentVideoBitrate > 400000)
{
@ -344,7 +344,7 @@ int VideoPacketSender::GetVideoResolutionForCurrentBitrate()
resolutionFromBitrate = INIT_VIDEO_RES_360;
}
}
else if (stream->codec == CODEC_HEVC || stream->codec == CODEC_VP9)
else if (stream->codec == Codec::Hevc || stream->codec == Codec::Vp9)
{
if (currentVideoBitrate > 400000)
{
@ -366,9 +366,9 @@ int VideoPacketSender::GetVideoResolutionForCurrentBitrate()
}
else
{
if (stream->codec == CODEC_AVC || stream->codec == CODEC_VP8)
if (stream->codec == Codec::Avc || stream->codec == Codec::Vp8)
resolutionFromBitrate = INIT_VIDEO_RES_720;
else if (stream->codec == CODEC_HEVC || stream->codec == CODEC_VP9)
else if (stream->codec == Codec::Hevc || stream->codec == Codec::Vp9)
resolutionFromBitrate = INIT_VIDEO_RES_1080;
}
return std::min(peerMaxVideoResolution, resolutionFromBitrate);