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:
parent
c81037e7ca
commit
4a1a910d0a
10
.clang-format
Normal file
10
.clang-format
Normal file
@ -0,0 +1,10 @@
|
||||
BasedOnStyle: LLVM
|
||||
UseTab: Never
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
BreakBeforeBraces: Allman
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
IndentCaseLabels: false
|
||||
ColumnLimit: 0
|
||||
AccessModifierOffset: -4
|
||||
|
@ -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 \
|
||||
|
42
Makefile.in
42
Makefile.in
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
115
controller/Constants.h
Normal 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
|
@ -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"
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
uint8_t ipv6[16];
|
||||
} addr;
|
||||
|
||||
private:
|
||||
public:
|
||||
NetworkAddress(){};
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
31
controller/protocol/VersionInfo.h
Normal file
31
controller/protocol/VersionInfo.h
Normal 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
|
@ -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
|
||||
{
|
||||
|
@ -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
|
2
controller/protocol/protocol/Index.h
Normal file
2
controller/protocol/protocol/Index.h
Normal file
@ -0,0 +1,2 @@
|
||||
#include "Extra.h"
|
||||
#include "Interface.h"
|
@ -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
|
@ -9,7 +9,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user