diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..5b1c726 --- /dev/null +++ b/.clang-format @@ -0,0 +1,10 @@ +BasedOnStyle: LLVM +UseTab: Never +IndentWidth: 4 +TabWidth: 4 +BreakBeforeBraces: Allman +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: false +ColumnLimit: 0 +AccessModifierOffset: -4 + diff --git a/Makefile.am b/Makefile.am index 021e0e9..bbcaeec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/Makefile.in b/Makefile.in index 480ecb3..ce25da0 100644 --- a/Makefile.in +++ b/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 diff --git a/VoIPController.h b/VoIPController.h index 7b62c5e..e6c5c06 100755 --- a/VoIPController.h +++ b/VoIPController.h @@ -6,6 +6,12 @@ #pragma once +#if defined HAVE_CONFIG_H || defined TGVOIP_USE_INSTALLED_OPUS +#include +#else +#include +#endif + #ifndef _WIN32 #include #include @@ -47,11 +53,6 @@ #include "tools/utils.h" #include "controller/PrivateDefines.h" -#if defined HAVE_CONFIG_H || defined TGVOIP_USE_INSTALLED_OPUS -#include -#else -#include -#endif #define LIBTGVOIP_VERSION "2.5" diff --git a/VoIPGroupController.cpp b/VoIPGroupController.cpp index 271c0ce..121ece4 100644 --- a/VoIPGroupController.cpp +++ b/VoIPGroupController.cpp @@ -95,7 +95,7 @@ void VoIPGroupController::AddGroupCallParticipant(int32_t userID, unsigned char { shared_ptr &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(s->frameDuration); @@ -165,10 +165,10 @@ vector> VoIPGroupController::DeserializeStrea BufferInputStream inner = in.GetPartBuffer(len, true); shared_ptr s = make_shared(); s->id = inner.ReadByte(); - s->type = static_cast(inner.ReadByte()); + s->type = static_cast(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>::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()); diff --git a/controller/Constants.h b/controller/Constants.h new file mode 100644 index 0000000..0dd7ff9 --- /dev/null +++ b/controller/Constants.h @@ -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 diff --git a/controller/PrivateDefines.h b/controller/PrivateDefines.h index cbbd410..0860142 100644 --- a/controller/PrivateDefines.h +++ b/controller/PrivateDefines.h @@ -5,134 +5,6 @@ #pragma once #include -// 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" \ No newline at end of file +#include "Constants.h" +#include "protocol/VersionInfo.h" +#include "protocol/protocol/Index.h" \ No newline at end of file diff --git a/controller/controller/Init.cpp b/controller/controller/Init.cpp index 9723c20..d28f110 100644 --- a/controller/controller/Init.cpp +++ b/controller/controller/Init.cpp @@ -37,8 +37,8 @@ VoIPController::VoIPController() : rawSendQueue(64) shared_ptr stm = make_shared(); 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(this, nullptr, stm); diff --git a/controller/controller/PublicAPI.cpp b/controller/controller/PublicAPI.cpp index 6e85ca8..c20216b 100644 --- a/controller/controller/PublicAPI.cpp +++ b/controller/controller/PublicAPI.cpp @@ -209,7 +209,7 @@ string VoIPController::GetDebugString() r += buffer; } double avgLate[3]; - shared_ptr stm = GetStreamByType(STREAM_TYPE_AUDIO, false); + shared_ptr stm = GetStreamByType(StreamInfo::Type::Audio, false); shared_ptr jitterBuffer; if (stm) jitterBuffer = stm->jitterBuffer; @@ -249,7 +249,7 @@ string VoIPController::GetDebugString() if (config.enableVideoSend) { - shared_ptr vstm = GetStreamByType(STREAM_TYPE_VIDEO, true); + shared_ptr 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(vstm->packetSender.get())->GetBitrate()); @@ -267,7 +267,7 @@ string VoIPController::GetDebugString() } if (config.enableVideoReceive) { - shared_ptr vstm = GetStreamByType(STREAM_TYPE_VIDEO, false); + shared_ptr 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(GetStreamByType(STREAM_TYPE_AUDIO, true)->packetSender.get())->setAudioPreprocDataCallback(preproc); + dynamic_cast(GetStreamByType(StreamInfo::Type::Audio, true)->packetSender.get())->setAudioPreprocDataCallback(preproc); } #endif diff --git a/controller/controller/Streams.cpp b/controller/controller/Streams.cpp index 6151bad..51f5eaf 100644 --- a/controller/controller/Streams.cpp +++ b/controller/controller/Streams.cpp @@ -4,7 +4,7 @@ using namespace tgvoip; using namespace std; -shared_ptr VoIPController::GetStreamByType(StreamType type, bool outgoing) +shared_ptr VoIPController::GetStreamByType(StreamInfo::Type type, bool outgoing) { for (shared_ptr &ss : (outgoing ? outgoingStreams : incomingStreams)) { diff --git a/controller/media/Audio.cpp b/controller/media/Audio.cpp index b33e1f9..cbbf94a 100644 --- a/controller/media/Audio.cpp +++ b/controller/media/Audio.cpp @@ -8,7 +8,7 @@ using namespace std; void VoIPController::InitializeAudio() { double t = GetCurrentTime(); - shared_ptr outgoingAudioStream = GetStreamByType(STREAM_TYPE_AUDIO, true); + shared_ptr 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) diff --git a/controller/media/Video.cpp b/controller/media/Video.cpp index 6d92689..aeaa276 100644 --- a/controller/media/Video.cpp +++ b/controller/media/Video.cpp @@ -7,7 +7,7 @@ using namespace std; void VoIPController::SetVideoSource(video::VideoSource *source) { - shared_ptr stm = GetStreamByType(STREAM_TYPE_VIDEO, true); + shared_ptr 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 stm = GetStreamByType(STREAM_TYPE_VIDEO, false); + shared_ptr stm = GetStreamByType(StreamInfo::Type::Video, false); size_t offset = 0; if (keyframe) { @@ -134,19 +134,19 @@ void VoIPController::SetupOutgoingVideoStream() vector myEncoders = video::VideoSource::GetAvailableEncoders(); shared_ptr vstm = make_shared(); 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 { diff --git a/controller/net/NetworkSocket.h b/controller/net/NetworkSocket.h index 4e39e5a..06ab3df 100644 --- a/controller/net/NetworkSocket.h +++ b/controller/net/NetworkSocket.h @@ -68,7 +68,7 @@ public: uint8_t ipv6[16]; } addr; -private: +public: NetworkAddress(){}; }; diff --git a/controller/protocol/Bandwidth.cpp b/controller/protocol/Bandwidth.cpp index 1ca8344..cfeebe0 100644 --- a/controller/protocol/Bandwidth.cpp +++ b/controller/protocol/Bandwidth.cpp @@ -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(); diff --git a/controller/protocol/NetworkAPI.cpp b/controller/protocol/NetworkAPI.cpp index 25867d4..1029196 100644 --- a/controller/protocol/NetworkAPI.cpp +++ b/controller/protocol/NetworkAPI.cpp @@ -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 decoders = config.enableVideoReceive ? video::VideoRenderer::GetAvailableDecoders() : vector(); vector encoders = config.enableVideoSend ? video::VideoSource::GetAvailableEncoders() : vector(); 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); } \ No newline at end of file diff --git a/controller/protocol/PacketStructs.cpp b/controller/protocol/PacketStructs.cpp index cfec767..d39a247 100644 --- a/controller/protocol/PacketStructs.cpp +++ b/controller/protocol/PacketStructs.cpp @@ -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) diff --git a/controller/protocol/PacketStructs.h b/controller/protocol/PacketStructs.h index 597479d..70b8366 100644 --- a/controller/protocol/PacketStructs.h +++ b/controller/protocol/PacketStructs.h @@ -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> &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> &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> &extras, const int state, const unsigned char *callID); public: enum Flags : uint8_t @@ -64,11 +68,11 @@ public: Mask> extraEC; Array> extraSignaling; - // Ugly backwards compatibility hack - std::vector otherPackets; - + // Ugly backwards compatibility hacks + std::vector otherPackets; // parse public: - operator bool() { + operator bool() + { return data || extraEC || extraSignaling || seq; } }; diff --git a/controller/protocol/PacketStructsLegacy.cpp b/controller/protocol/PacketStructsLegacy.cpp index e94afbb..8dbc0ed 100644 --- a/controller/protocol/PacketStructsLegacy.cpp +++ b/controller/protocol/PacketStructsLegacy.cpp @@ -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> &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> separatePackets; + std::vector> 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) { // 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 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(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(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> 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(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(data.Length()); + if (hasExtraFEC) + lenAndFlags |= STREAM_DATA_XFLAG_EXTRA_FEC; + out.WriteInt16(lenAndFlags); + } + else + { + out.WriteByte(static_cast(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> &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(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> &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(currentExtras.size())); - for (vector::iterator x = currentExtras.begin(); x != currentExtras.end(); ++x) + out.WriteByte(static_cast(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(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); } } } diff --git a/controller/protocol/Protocol.cpp b/controller/protocol/Protocol.cpp index 937a7d2..fe8c58a 100644 --- a/controller/protocol/Protocol.cpp +++ b/controller/protocol/Protocol.cpp @@ -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 stm = make_shared(); stm->id = in.ReadByte(); - stm->type = static_cast(in.ReadByte()); + stm->type = static_cast(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(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 videoStream = GetStreamByType(STREAM_TYPE_VIDEO, false); + shared_ptr 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()) diff --git a/controller/protocol/Reflector.cpp b/controller/protocol/Reflector.cpp index b5e453d..c5ac3f9 100644 --- a/controller/protocol/Reflector.cpp +++ b/controller/protocol/Reflector.cpp @@ -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; diff --git a/controller/protocol/Tick.cpp b/controller/protocol/Tick.cpp index 8e749f9..9cc716a 100644 --- a/controller/protocol/Tick.cpp +++ b/controller/protocol/Tick.cpp @@ -196,7 +196,7 @@ void VoIPController::UpdateCongestion() double avgSendLossCount = sendLossCountHistory.Average() / packetCountHistory.Average(); LOGE("avg send loss: %.3f%%", avgSendLossCount*100); - AudioPacketSender *sender = dynamic_cast(GetStreamByType(STREAM_TYPE_AUDIO, true)->packetSender.get()); + AudioPacketSender *sender = dynamic_cast(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 &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 &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(GetStreamByType(STREAM_TYPE_AUDIO, true)->packetSender.get())->getShittyInternetMode()) + if (dynamic_cast(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; } diff --git a/controller/protocol/VersionInfo.h b/controller/protocol/VersionInfo.h new file mode 100644 index 0000000..6cd9686 --- /dev/null +++ b/controller/protocol/VersionInfo.h @@ -0,0 +1,31 @@ +#include + +// 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 \ No newline at end of file diff --git a/controller/protocol/protocol/Extra.cpp b/controller/protocol/protocol/Extra.cpp index 54fddd0..487ea85 100644 --- a/controller/protocol/protocol/Extra.cpp +++ b/controller/protocol/protocol/Extra.cpp @@ -1,4 +1,5 @@ #include "Extra.h" +#include "../../PrivateDefines.h" using namespace tgvoip; @@ -78,6 +79,33 @@ std::shared_ptr 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 { diff --git a/controller/protocol/protocol/Extra.h b/controller/protocol/protocol/Extra.h index 6bfccd9..c214700 100644 --- a/controller/protocol/protocol/Extra.h +++ b/controller/protocol/protocol/Extra.h @@ -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 { + static std::shared_ptr choose(const BufferInputStream &in, const VersionInfo &ver); static std::shared_ptr chooseFromType(uint8_t type); + uint8_t chooseType(int peerVersion) const; }; struct Codec : public Serializable, SingleChoice @@ -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 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 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 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 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 \ No newline at end of file diff --git a/controller/protocol/protocol/Index.h b/controller/protocol/protocol/Index.h new file mode 100644 index 0000000..0322bb0 --- /dev/null +++ b/controller/protocol/protocol/Index.h @@ -0,0 +1,2 @@ +#include "Extra.h" +#include "Interface.h" diff --git a/controller/protocol/protocol/Interface.h b/controller/protocol/protocol/Interface.h index 71bfb72..0aa03f6 100644 --- a/controller/protocol/protocol/Interface.h +++ b/controller/protocol/protocol/Interface.h @@ -1,21 +1,11 @@ #pragma once #include "../../../tools/Buffers.h" #include +#include 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 struct SingleChoice @@ -24,12 +14,53 @@ struct SingleChoice { return std::make_shared(); } + + uint8_t getID() const + { + return 0; + } + + static const uint8_t ID = 0; }; template struct MultiChoice { - static std::shared_ptr choose(const BufferInputStream &in, const VersionInfo &ver); +private: + static std::shared_ptr __forceChoice(const BufferInputStream &in, const VersionInfo &ver) + { + return T::choose(in, ver); + } + +public: + virtual uint8_t getID() const = 0; +}; + +template +struct has_flags : std::false_type +{ +}; + +template +struct has_flags> : std::true_type +{ +}; + +struct Empty +{ + enum Flags : uint8_t + { + }; +}; + +template +struct Constructor // : public T +{ + uint8_t getID() const + { + return T::ID; + } + using Flags = typename std::conditional::value, T, Empty>::type::Flags; }; struct Serializable @@ -49,7 +80,7 @@ struct Mask : public Serializable, SingleChoice> { 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> 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> out.WriteByte(mask); for (const auto &data : v) { - out.Write(v, data); + out.Write(data, ver); } } - typename std::array::iterator begin() + auto begin() noexcept { return v.begin(); } - typename std::array::iterator end() + auto end() noexcept { return v.end(); } - typename std::array::const_iterator cbegin() + const auto begin() const noexcept { - return v.cbegin(); + return v.begin(); } - typename std::array::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> data.serialize(out, ver); } } - typename std::vector::iterator begin() + auto begin() noexcept { return v.begin(); } - typename std::vector::iterator end() + auto end() noexcept { return v.end(); } - typename std::vector::const_iterator cbegin() + const auto begin() const noexcept { - return v.cbegin(); + return v.begin(); } - typename std::vector::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> 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> { return d && *d; } + + uint8_t getID() const + { + return d->getID(); + } + + template + X &get() + { + return *dynamic_cast(d.get()); + } + + template + const X &get() const + { + return *dynamic_cast(d.get()); + } + + template + operator X &() + { + return *dynamic_cast(d.get()); + } + + template + operator const X &() const + { + return *dynamic_cast(d.get()); + } + std::shared_ptr 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 { bool parse(const BufferInputStream &in, const VersionInfo &ver) @@ -218,4 +282,12 @@ struct UInt32 : public Serializable, SingleChoice } uint32_t data; }; + +namespace Template +{ +template +struct Constructor : public T, tgvoip::Constructor +{ +}; +}; // namespace Template } // namespace tgvoip \ No newline at end of file diff --git a/tools/Buffers.h b/tools/Buffers.h index 21a0eae..9f551a8 100644 --- a/tools/Buffers.h +++ b/tools/Buffers.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/tools/utils.h b/tools/utils.h index 92655ce..d4f0ba8 100644 --- a/tools/utils.h +++ b/tools/utils.h @@ -7,6 +7,7 @@ #pragma once #include #include +#include #define TGVOIP_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ @@ -44,9 +45,9 @@ public: { AVG_T avg = static_cast(0); int nonZeroCount = 0; - for (T &i : data) + for (const T &i : data) { - if (i != 0) + if (i) { nonZeroCount++; avg += i; diff --git a/video/VideoPacketSender.cpp b/video/VideoPacketSender.cpp index 8c4825f..728c3e2 100644 --- a/video/VideoPacketSender.cpp +++ b/video/VideoPacketSender.cpp @@ -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);