1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-30 04:39:03 +01:00

Cleanup classes a bit, preparing for my strategy

This commit is contained in:
Daniil Gentili 2020-01-23 16:45:53 +01:00
parent 8bfbecb8f5
commit d2979cb7bb
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
18 changed files with 468 additions and 414 deletions

1
.gitignore vendored
View File

@ -27,3 +27,4 @@ autom4te.cache/
*.o *.o
*.Plo *.Plo
*.lo *.lo
.vscode

View File

@ -14,6 +14,7 @@ tools/logging.cpp \
controller/MediaStreamItf.cpp \ controller/MediaStreamItf.cpp \
tools/MessageThread.cpp \ tools/MessageThread.cpp \
controller/net/NetworkSocket.cpp \ controller/net/NetworkSocket.cpp \
controller/net/Endpoint.cpp \
controller/audio/OpusDecoder.cpp \ controller/audio/OpusDecoder.cpp \
controller/audio/OpusEncoder.cpp \ controller/audio/OpusEncoder.cpp \
controller/PacketReassembler.cpp \ controller/PacketReassembler.cpp \
@ -23,6 +24,7 @@ audio/AudioIO.cpp \
audio/AudioInput.cpp \ audio/AudioInput.cpp \
audio/AudioOutput.cpp \ audio/AudioOutput.cpp \
audio/Resampler.cpp \ audio/Resampler.cpp \
audio/AudioInputTester.cpp \
os/posix/NetworkSocketPosix.cpp \ os/posix/NetworkSocketPosix.cpp \
video/VideoSource.cpp \ video/VideoSource.cpp \
video/VideoRenderer.cpp \ video/VideoRenderer.cpp \

View File

@ -813,16 +813,17 @@ am__libtgvoip_la_SOURCES_DIST = TgVoip.cpp VoIPController.cpp \
controller/audio/EchoCanceller.cpp \ controller/audio/EchoCanceller.cpp \
controller/net/JitterBuffer.cpp tools/logging.cpp \ controller/net/JitterBuffer.cpp tools/logging.cpp \
controller/MediaStreamItf.cpp tools/MessageThread.cpp \ controller/MediaStreamItf.cpp tools/MessageThread.cpp \
controller/net/NetworkSocket.cpp \ controller/net/NetworkSocket.cpp controller/net/Endpoint.cpp \
controller/audio/OpusDecoder.cpp \ controller/audio/OpusDecoder.cpp \
controller/audio/OpusEncoder.cpp \ controller/audio/OpusEncoder.cpp \
controller/PacketReassembler.cpp VoIPGroupController.cpp \ controller/PacketReassembler.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \ VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \ audio/AudioOutput.cpp audio/Resampler.cpp \
os/posix/NetworkSocketPosix.cpp video/VideoSource.cpp \ audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
video/VideoRenderer.cpp video/VideoPacketSender.cpp \ video/VideoSource.cpp video/VideoRenderer.cpp \
video/VideoFEC.cpp video/ScreamCongestionController.cpp \ video/VideoPacketSender.cpp video/VideoFEC.cpp \
tools/json11.cpp os/darwin/AudioInputAudioUnit.cpp \ video/ScreamCongestionController.cpp tools/json11.cpp \
os/darwin/AudioInputAudioUnit.cpp \
os/darwin/AudioOutputAudioUnit.cpp os/darwin/AudioUnitIO.cpp \ os/darwin/AudioOutputAudioUnit.cpp os/darwin/AudioUnitIO.cpp \
os/darwin/AudioInputAudioUnitOSX.cpp \ os/darwin/AudioInputAudioUnitOSX.cpp \
os/darwin/AudioOutputAudioUnitOSX.cpp \ os/darwin/AudioOutputAudioUnitOSX.cpp \
@ -1750,19 +1751,20 @@ am__objects_12 = TgVoip.lo VoIPController.lo tools/Buffers.lo \
controller/audio/EchoCanceller.lo \ controller/audio/EchoCanceller.lo \
controller/net/JitterBuffer.lo tools/logging.lo \ controller/net/JitterBuffer.lo tools/logging.lo \
controller/MediaStreamItf.lo tools/MessageThread.lo \ controller/MediaStreamItf.lo tools/MessageThread.lo \
controller/net/NetworkSocket.lo \ controller/net/NetworkSocket.lo controller/net/Endpoint.lo \
controller/audio/OpusDecoder.lo \ controller/audio/OpusDecoder.lo \
controller/audio/OpusEncoder.lo \ controller/audio/OpusEncoder.lo \
controller/PacketReassembler.lo VoIPGroupController.lo \ controller/PacketReassembler.lo VoIPGroupController.lo \
VoIPServerConfig.lo audio/AudioIO.lo audio/AudioInput.lo \ VoIPServerConfig.lo audio/AudioIO.lo audio/AudioInput.lo \
audio/AudioOutput.lo audio/Resampler.lo \ audio/AudioOutput.lo audio/Resampler.lo \
os/posix/NetworkSocketPosix.lo video/VideoSource.lo \ audio/AudioInputTester.lo os/posix/NetworkSocketPosix.lo \
video/VideoRenderer.lo video/VideoPacketSender.lo \ video/VideoSource.lo video/VideoRenderer.lo \
video/VideoFEC.lo video/ScreamCongestionController.lo \ video/VideoPacketSender.lo video/VideoFEC.lo \
tools/json11.lo $(am__objects_1) $(am__objects_2) \ video/ScreamCongestionController.lo tools/json11.lo \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_9) $(am__objects_10) $(am__objects_11) $(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11)
am__objects_13 = $(am__objects_11) $(am__objects_11) $(am__objects_11) \ am__objects_13 = $(am__objects_11) $(am__objects_11) $(am__objects_11) \
$(am__objects_11) $(am__objects_11)
am_libtgvoip_la_OBJECTS = $(am__objects_12) $(am__objects_13) am_libtgvoip_la_OBJECTS = $(am__objects_12) $(am__objects_13)
@ -2055,14 +2057,16 @@ am__depfiles_remade = ./$(DEPDIR)/TgVoip.Plo \
./webrtc_dsp/third_party/rnnoise/src/$(DEPDIR)/rnn_vad_weights.Plo \ ./webrtc_dsp/third_party/rnnoise/src/$(DEPDIR)/rnn_vad_weights.Plo \
audio/$(DEPDIR)/AudioIO.Plo \ audio/$(DEPDIR)/AudioIO.Plo \
audio/$(DEPDIR)/AudioIOCallback.Plo \ audio/$(DEPDIR)/AudioIOCallback.Plo \
audio/$(DEPDIR)/AudioInput.Plo audio/$(DEPDIR)/AudioOutput.Plo \ audio/$(DEPDIR)/AudioInput.Plo \
audio/$(DEPDIR)/Resampler.Plo \ audio/$(DEPDIR)/AudioInputTester.Plo \
audio/$(DEPDIR)/AudioOutput.Plo audio/$(DEPDIR)/Resampler.Plo \
controller/$(DEPDIR)/MediaStreamItf.Plo \ controller/$(DEPDIR)/MediaStreamItf.Plo \
controller/$(DEPDIR)/PacketReassembler.Plo \ controller/$(DEPDIR)/PacketReassembler.Plo \
controller/audio/$(DEPDIR)/EchoCanceller.Plo \ controller/audio/$(DEPDIR)/EchoCanceller.Plo \
controller/audio/$(DEPDIR)/OpusDecoder.Plo \ controller/audio/$(DEPDIR)/OpusDecoder.Plo \
controller/audio/$(DEPDIR)/OpusEncoder.Plo \ controller/audio/$(DEPDIR)/OpusEncoder.Plo \
controller/net/$(DEPDIR)/CongestionControl.Plo \ controller/net/$(DEPDIR)/CongestionControl.Plo \
controller/net/$(DEPDIR)/Endpoint.Plo \
controller/net/$(DEPDIR)/JitterBuffer.Plo \ controller/net/$(DEPDIR)/JitterBuffer.Plo \
controller/net/$(DEPDIR)/NetworkSocket.Plo \ controller/net/$(DEPDIR)/NetworkSocket.Plo \
os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo \ os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo \
@ -2376,19 +2380,20 @@ SRC = TgVoip.cpp VoIPController.cpp tools/Buffers.cpp \
controller/audio/EchoCanceller.cpp \ controller/audio/EchoCanceller.cpp \
controller/net/JitterBuffer.cpp tools/logging.cpp \ controller/net/JitterBuffer.cpp tools/logging.cpp \
controller/MediaStreamItf.cpp tools/MessageThread.cpp \ controller/MediaStreamItf.cpp tools/MessageThread.cpp \
controller/net/NetworkSocket.cpp \ controller/net/NetworkSocket.cpp controller/net/Endpoint.cpp \
controller/audio/OpusDecoder.cpp \ controller/audio/OpusDecoder.cpp \
controller/audio/OpusEncoder.cpp \ controller/audio/OpusEncoder.cpp \
controller/PacketReassembler.cpp VoIPGroupController.cpp \ controller/PacketReassembler.cpp VoIPGroupController.cpp \
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \ VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
audio/AudioOutput.cpp audio/Resampler.cpp \ audio/AudioOutput.cpp audio/Resampler.cpp \
os/posix/NetworkSocketPosix.cpp video/VideoSource.cpp \ audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
video/VideoRenderer.cpp video/VideoPacketSender.cpp \ video/VideoSource.cpp video/VideoRenderer.cpp \
video/VideoFEC.cpp video/ScreamCongestionController.cpp \ video/VideoPacketSender.cpp video/VideoFEC.cpp \
tools/json11.cpp $(am__append_1) $(am__append_4) \ video/ScreamCongestionController.cpp tools/json11.cpp \
$(am__append_6) $(am__append_10) $(am__append_12) \ $(am__append_1) $(am__append_4) $(am__append_6) \
$(am__append_14) $(am__append_16) $(am__append_18) \ $(am__append_10) $(am__append_12) $(am__append_14) \
$(am__append_21) $(am__append_22) $(am__append_23) $(am__append_16) $(am__append_18) $(am__append_21) \
$(am__append_22) $(am__append_23)
TGVOIP_HDRS = TgVoip.h VoIPController.h tools/Buffers.h \ TGVOIP_HDRS = TgVoip.h VoIPController.h tools/Buffers.h \
tools/BlockingQueue.h controller/PrivateDefines.h \ tools/BlockingQueue.h controller/PrivateDefines.h \
controller/net/CongestionControl.h \ controller/net/CongestionControl.h \
@ -2535,6 +2540,8 @@ tools/MessageThread.lo: tools/$(am__dirstamp) \
tools/$(DEPDIR)/$(am__dirstamp) tools/$(DEPDIR)/$(am__dirstamp)
controller/net/NetworkSocket.lo: controller/net/$(am__dirstamp) \ controller/net/NetworkSocket.lo: controller/net/$(am__dirstamp) \
controller/net/$(DEPDIR)/$(am__dirstamp) controller/net/$(DEPDIR)/$(am__dirstamp)
controller/net/Endpoint.lo: controller/net/$(am__dirstamp) \
controller/net/$(DEPDIR)/$(am__dirstamp)
controller/audio/OpusDecoder.lo: controller/audio/$(am__dirstamp) \ controller/audio/OpusDecoder.lo: controller/audio/$(am__dirstamp) \
controller/audio/$(DEPDIR)/$(am__dirstamp) controller/audio/$(DEPDIR)/$(am__dirstamp)
controller/audio/OpusEncoder.lo: controller/audio/$(am__dirstamp) \ controller/audio/OpusEncoder.lo: controller/audio/$(am__dirstamp) \
@ -2555,6 +2562,8 @@ audio/AudioOutput.lo: audio/$(am__dirstamp) \
audio/$(DEPDIR)/$(am__dirstamp) audio/$(DEPDIR)/$(am__dirstamp)
audio/Resampler.lo: audio/$(am__dirstamp) \ audio/Resampler.lo: audio/$(am__dirstamp) \
audio/$(DEPDIR)/$(am__dirstamp) audio/$(DEPDIR)/$(am__dirstamp)
audio/AudioInputTester.lo: audio/$(am__dirstamp) \
audio/$(DEPDIR)/$(am__dirstamp)
os/posix/$(am__dirstamp): os/posix/$(am__dirstamp):
@$(MKDIR_P) os/posix @$(MKDIR_P) os/posix
@: > os/posix/$(am__dirstamp) @: > os/posix/$(am__dirstamp)
@ -3991,6 +4000,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioIO.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioIO.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioIOCallback.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioIOCallback.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioInput.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioInput.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioInputTester.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioOutput.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/AudioOutput.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/Resampler.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/Resampler.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/$(DEPDIR)/MediaStreamItf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@controller/$(DEPDIR)/MediaStreamItf.Plo@am__quote@ # am--include-marker
@ -3999,6 +4009,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@controller/audio/$(DEPDIR)/OpusDecoder.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@controller/audio/$(DEPDIR)/OpusDecoder.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/audio/$(DEPDIR)/OpusEncoder.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@controller/audio/$(DEPDIR)/OpusEncoder.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/CongestionControl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/CongestionControl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/Endpoint.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/JitterBuffer.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/JitterBuffer.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/NetworkSocket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@controller/net/$(DEPDIR)/NetworkSocket.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)/AudioInputAudioUnit.Plo@am__quote@ # am--include-marker
@ -4874,6 +4885,7 @@ distclean: distclean-am
-rm -f audio/$(DEPDIR)/AudioIO.Plo -rm -f audio/$(DEPDIR)/AudioIO.Plo
-rm -f audio/$(DEPDIR)/AudioIOCallback.Plo -rm -f audio/$(DEPDIR)/AudioIOCallback.Plo
-rm -f audio/$(DEPDIR)/AudioInput.Plo -rm -f audio/$(DEPDIR)/AudioInput.Plo
-rm -f audio/$(DEPDIR)/AudioInputTester.Plo
-rm -f audio/$(DEPDIR)/AudioOutput.Plo -rm -f audio/$(DEPDIR)/AudioOutput.Plo
-rm -f audio/$(DEPDIR)/Resampler.Plo -rm -f audio/$(DEPDIR)/Resampler.Plo
-rm -f controller/$(DEPDIR)/MediaStreamItf.Plo -rm -f controller/$(DEPDIR)/MediaStreamItf.Plo
@ -4882,6 +4894,7 @@ distclean: distclean-am
-rm -f controller/audio/$(DEPDIR)/OpusDecoder.Plo -rm -f controller/audio/$(DEPDIR)/OpusDecoder.Plo
-rm -f controller/audio/$(DEPDIR)/OpusEncoder.Plo -rm -f controller/audio/$(DEPDIR)/OpusEncoder.Plo
-rm -f controller/net/$(DEPDIR)/CongestionControl.Plo -rm -f controller/net/$(DEPDIR)/CongestionControl.Plo
-rm -f controller/net/$(DEPDIR)/Endpoint.Plo
-rm -f controller/net/$(DEPDIR)/JitterBuffer.Plo -rm -f controller/net/$(DEPDIR)/JitterBuffer.Plo
-rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo -rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo -rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo
@ -5240,6 +5253,7 @@ maintainer-clean: maintainer-clean-am
-rm -f audio/$(DEPDIR)/AudioIO.Plo -rm -f audio/$(DEPDIR)/AudioIO.Plo
-rm -f audio/$(DEPDIR)/AudioIOCallback.Plo -rm -f audio/$(DEPDIR)/AudioIOCallback.Plo
-rm -f audio/$(DEPDIR)/AudioInput.Plo -rm -f audio/$(DEPDIR)/AudioInput.Plo
-rm -f audio/$(DEPDIR)/AudioInputTester.Plo
-rm -f audio/$(DEPDIR)/AudioOutput.Plo -rm -f audio/$(DEPDIR)/AudioOutput.Plo
-rm -f audio/$(DEPDIR)/Resampler.Plo -rm -f audio/$(DEPDIR)/Resampler.Plo
-rm -f controller/$(DEPDIR)/MediaStreamItf.Plo -rm -f controller/$(DEPDIR)/MediaStreamItf.Plo
@ -5248,6 +5262,7 @@ maintainer-clean: maintainer-clean-am
-rm -f controller/audio/$(DEPDIR)/OpusDecoder.Plo -rm -f controller/audio/$(DEPDIR)/OpusDecoder.Plo
-rm -f controller/audio/$(DEPDIR)/OpusEncoder.Plo -rm -f controller/audio/$(DEPDIR)/OpusEncoder.Plo
-rm -f controller/net/$(DEPDIR)/CongestionControl.Plo -rm -f controller/net/$(DEPDIR)/CongestionControl.Plo
-rm -f controller/net/$(DEPDIR)/Endpoint.Plo
-rm -f controller/net/$(DEPDIR)/JitterBuffer.Plo -rm -f controller/net/$(DEPDIR)/JitterBuffer.Plo
-rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo -rm -f controller/net/$(DEPDIR)/NetworkSocket.Plo
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo -rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo

View File

@ -19,6 +19,7 @@
#include "controller/audio/OpusDecoder.h" #include "controller/audio/OpusDecoder.h"
#include "VoIPServerConfig.h" #include "VoIPServerConfig.h"
#include "controller/PrivateDefines.h" #include "controller/PrivateDefines.h"
#include "controller/net/Endpoint.h"
#include "tools/json11.hpp" #include "tools/json11.hpp"
#include "controller/PacketSender.h" #include "controller/PacketSender.h"
#include "video/VideoPacketSender.h" #include "video/VideoPacketSender.h"
@ -425,7 +426,7 @@ void VoIPController::SetNetworkType(int type)
if (_preferredRelay.type == Endpoint::Type::UDP_RELAY) if (_preferredRelay.type == Endpoint::Type::UDP_RELAY)
currentEndpoint = preferredRelay; currentEndpoint = preferredRelay;
MutexGuard m(endpointsMutex); MutexGuard m(endpointsMutex);
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32; constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
endpoints.erase(lanID); endpoints.erase(lanID);
for (pair<const int64_t, Endpoint> &e : endpoints) for (pair<const int64_t, Endpoint> &e : endpoints)
{ {
@ -2095,9 +2096,9 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
size_t len = packet.data.Length(); size_t len = packet.data.Length();
BufferInputStream in(packet.data); BufferInputStream in(packet.data);
bool hasPeerTag = false; bool hasPeerTag = false;
if (peerVersion < 9 || srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY) if (peerVersion < 9 || srcEndpoint.IsReflector())
{ {
if (memcmp(buffer, srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY ? (void *)srcEndpoint.peerTag : (void *)callID, 16) != 0) if (memcmp(buffer, srcEndpoint.IsReflector() ? (void *)srcEndpoint.peerTag : (void *)callID, 16) != 0)
{ {
LOGW("Received packet has wrong peerTag"); LOGW("Received packet has wrong peerTag");
return; return;
@ -2105,7 +2106,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
in.Seek(16); in.Seek(16);
hasPeerTag = true; hasPeerTag = true;
} }
if (in.Remaining() >= 16 && (srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY) && *reinterpret_cast<uint64_t *>(buffer + 16) == 0xFFFFFFFFFFFFFFFFLL && *reinterpret_cast<uint32_t *>(buffer + 24) == 0xFFFFFFFF) if (in.Remaining() >= 16 && srcEndpoint.IsReflector() && *reinterpret_cast<uint64_t *>(buffer + 16) == 0xFFFFFFFFFFFFFFFFLL && *reinterpret_cast<uint32_t *>(buffer + 24) == 0xFFFFFFFF)
{ {
// relay special request response // relay special request response
in.Seek(16 + 12); in.Seek(16 + 12);
@ -2160,8 +2161,8 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
uint32_t peerAddr = (uint32_t)in.ReadInt32(); uint32_t peerAddr = (uint32_t)in.ReadInt32();
uint32_t peerPort = (uint32_t)in.ReadInt32(); uint32_t peerPort = (uint32_t)in.ReadInt32();
constexpr int64_t p2pID = (int64_t)(FOURCC('P', '2', 'P', '4')) << 32; constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '4')) << 32;
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32; constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
if (currentEndpoint == p2pID || currentEndpoint == lanID) if (currentEndpoint == p2pID || currentEndpoint == lanID)
currentEndpoint = preferredRelay; currentEndpoint = preferredRelay;
@ -2583,7 +2584,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
} }
Endpoint *_currentEndpoint = &endpoints.at(currentEndpoint); Endpoint *_currentEndpoint = &endpoints.at(currentEndpoint);
if (srcEndpoint.id != currentEndpoint && (srcEndpoint.type == Endpoint::Type::UDP_RELAY || srcEndpoint.type == Endpoint::Type::TCP_RELAY) && ((_currentEndpoint->type != Endpoint::Type::UDP_RELAY && _currentEndpoint->type != Endpoint::Type::TCP_RELAY) || _currentEndpoint->averageRTT == 0)) if (srcEndpoint.id != currentEndpoint && srcEndpoint.IsReflector() && ((_currentEndpoint->type != Endpoint::Type::UDP_RELAY && _currentEndpoint->type != Endpoint::Type::TCP_RELAY) || _currentEndpoint->averageRTT == 0))
{ {
if (seqgt(lastSentSeq - 32, lastRemoteAckSeq)) if (seqgt(lastSentSeq - 32, lastRemoteAckSeq))
{ {
@ -3034,7 +3035,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
LOGV("received lan endpoint"); LOGV("received lan endpoint");
uint32_t peerAddr = (uint32_t)in.ReadInt32(); uint32_t peerAddr = (uint32_t)in.ReadInt32();
uint16_t peerPort = (uint16_t)in.ReadInt32(); uint16_t peerPort = (uint16_t)in.ReadInt32();
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32; constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
unsigned char peerTag[16]; unsigned char peerTag[16];
Endpoint lan(lanID, peerPort, NetworkAddress::IPv4(peerAddr), NetworkAddress::Empty(), Endpoint::Type::UDP_P2P_LAN, peerTag); Endpoint lan(lanID, peerPort, NetworkAddress::IPv4(peerAddr), NetworkAddress::Empty(), Endpoint::Type::UDP_P2P_LAN, peerTag);
@ -3209,7 +3210,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
LOGV("received lan endpoint (extra)"); LOGV("received lan endpoint (extra)");
uint32_t peerAddr = (uint32_t)in.ReadInt32(); uint32_t peerAddr = (uint32_t)in.ReadInt32();
uint16_t peerPort = (uint16_t)in.ReadInt32(); uint16_t peerPort = (uint16_t)in.ReadInt32();
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32; constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
if (currentEndpoint == lanID) if (currentEndpoint == lanID)
currentEndpoint = preferredRelay; currentEndpoint = preferredRelay;
@ -3268,7 +3269,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
peerIPv6Available = true; peerIPv6Available = true;
LOGV("Received peer IPv6 endpoint [%s]:%u", addr.ToString().c_str(), port); LOGV("Received peer IPv6 endpoint [%s]:%u", addr.ToString().c_str(), port);
constexpr int64_t p2pID = (int64_t)(FOURCC('P', '2', 'P', '6')) << 32; constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '6')) << 32;
Endpoint ep; Endpoint ep;
ep.type = Endpoint::Type::UDP_P2P_INET; ep.type = Endpoint::Type::UDP_P2P_INET;
@ -3390,7 +3391,7 @@ void VoIPController::SendPacket(unsigned char *data, size_t len, Endpoint &ep, P
if (ep.type == Endpoint::Type::TCP_RELAY && !useTCP) if (ep.type == Endpoint::Type::TCP_RELAY && !useTCP)
return; return;
BufferOutputStream out(len + 128); BufferOutputStream out(len + 128);
if (ep.type == Endpoint::Type::UDP_RELAY || ep.type == Endpoint::Type::TCP_RELAY) if (ep.IsReflector())
out.WriteBytes((unsigned char *)ep.peerTag, 16); out.WriteBytes((unsigned char *)ep.peerTag, 16);
else if (peerVersion < 9) else if (peerVersion < 9)
out.WriteBytes(callID, 16); out.WriteBytes(callID, 16);
@ -3465,19 +3466,14 @@ void VoIPController::SendPacket(unsigned char *data, size_t len, Endpoint &ep, P
LOGV("Sending: to=%s:%u, seq=%u, length=%u, type=%s", ep.GetAddress().ToString().c_str(), ep.port, srcPacket.seq, (unsigned int)out.GetLength(), GetPacketTypeString(srcPacket.type).c_str()); LOGV("Sending: to=%s:%u, seq=%u, length=%u, type=%s", ep.GetAddress().ToString().c_str(), ep.port, srcPacket.seq, (unsigned int)out.GetLength(), GetPacketTypeString(srcPacket.type).c_str());
#endif #endif
/*ActuallySendPacket(NetworkPacket{ rawSendQueue.Put(
Buffer(std::move(out)), RawPendingOutgoingPacket{
ep.GetAddress(), NetworkPacket{
ep.port, Buffer(std::move(out)),
ep.type==Endpoint::Type::TCP_RELAY ? NetworkProtocol::TCP : NetworkProtocol::UDP ep.GetAddress(),
}, ep);*/ ep.port,
rawSendQueue.Put(RawPendingOutgoingPacket{ ep.type == Endpoint::Type::TCP_RELAY ? NetworkProtocol::TCP : NetworkProtocol::UDP},
NetworkPacket{ ep.type == Endpoint::Type::TCP_RELAY ? ep.socket : nullptr});
Buffer(std::move(out)),
ep.GetAddress(),
ep.port,
ep.type == Endpoint::Type::TCP_RELAY ? NetworkProtocol::TCP : NetworkProtocol::UDP},
ep.type == Endpoint::Type::TCP_RELAY ? ep.socket : nullptr});
} }
void VoIPController::ActuallySendPacket(NetworkPacket pkt, Endpoint &ep) void VoIPController::ActuallySendPacket(NetworkPacket pkt, Endpoint &ep)
@ -3556,21 +3552,18 @@ std::string VoIPController::GetPacketTypeString(unsigned char type)
case PKT_STREAM_EC: case PKT_STREAM_EC:
return "stream_ec"; return "stream_ec";
} }
char buf[255]; return string("unknown(") + std::to_string(type) + ')';
snprintf(buf, sizeof(buf), "unknown(%u)", type);
return string(buf);
} }
void VoIPController::AddIPv6Relays() void VoIPController::AddIPv6Relays()
{ {
if (!myIPv6.IsEmpty() && !didAddIPv6Relays) if (!myIPv6.IsEmpty() && !didAddIPv6Relays)
{ {
unordered_map<string, vector<Endpoint>> endpointsByAddress; unordered_map<string, vector<Endpoint>> endpointsByAddress;
for (pair<const int64_t, Endpoint> &_e : endpoints) for (pair<const int64_t, Endpoint> &_e : endpoints)
{ {
Endpoint &e = _e.second; Endpoint &e = _e.second;
if ((e.type == Endpoint::Type::UDP_RELAY || e.type == Endpoint::Type::TCP_RELAY) && !e.v6address.IsEmpty() && !e.address.IsEmpty()) if ((e.IsReflector()) && !e.v6address.IsEmpty() && !e.address.IsEmpty())
{ {
endpointsByAddress[e.v6address.ToString()].push_back(e); endpointsByAddress[e.v6address.ToString()].push_back(e);
} }
@ -3582,7 +3575,7 @@ void VoIPController::AddIPv6Relays()
{ {
didAddIPv6Relays = true; didAddIPv6Relays = true;
e.address = NetworkAddress::Empty(); e.address = NetworkAddress::Empty();
e.id = e.id ^ ((int64_t)(FOURCC('I', 'P', 'v', '6')) << 32); e.id = e.id ^ (static_cast<int64_t>(FOURCC('I', 'P', 'v', '6')) << 32);
e.averageRTT = 0; e.averageRTT = 0;
e.lastPingSeq = 0; e.lastPingSeq = 0;
e.lastPingTime = 0; e.lastPingTime = 0;
@ -3621,7 +3614,7 @@ void VoIPController::AddTCPRelays()
tcpRelay.lastPingTime = 0; tcpRelay.lastPingTime = 0;
tcpRelay.rtts.Reset(); tcpRelay.rtts.Reset();
tcpRelay.udpPongCount = 0; tcpRelay.udpPongCount = 0;
tcpRelay.id = tcpRelay.id ^ ((int64_t)(FOURCC('T', 'C', 'P', 0)) << 32); tcpRelay.id = tcpRelay.id ^ (static_cast<int64_t>(FOURCC('T', 'C', 'P', 0)) << 32);
if (setCurrentEndpointToTCP && endpoints.at(currentEndpoint).type != Endpoint::Type::TCP_RELAY) if (setCurrentEndpointToTCP && endpoints.at(currentEndpoint).type != Endpoint::Type::TCP_RELAY)
{ {
LOGV("Setting current endpoint to TCP"); LOGV("Setting current endpoint to TCP");
@ -3750,7 +3743,7 @@ void VoIPController::SendPublicEndpointsRequest(const Endpoint &relay)
NetworkProtocol::UDP}); NetworkProtocol::UDP});
} }
Endpoint &VoIPController::GetEndpointByType(int type) Endpoint &VoIPController::GetEndpointByType(const Endpoint::Type type)
{ {
if (type == Endpoint::Type::UDP_RELAY && preferredRelay) if (type == Endpoint::Type::UDP_RELAY && preferredRelay)
return endpoints.at(preferredRelay); return endpoints.at(preferredRelay);
@ -4168,7 +4161,7 @@ void VoIPController::SendRelayPings()
preferredRelay = minPingRelay->id; preferredRelay = minPingRelay->id;
_preferredRelay = minPingRelay; _preferredRelay = minPingRelay;
LOGV("set preferred relay to %s", _preferredRelay->address.ToString().c_str()); LOGV("set preferred relay to %s", _preferredRelay->address.ToString().c_str());
if (_currentEndpoint->type == Endpoint::Type::UDP_RELAY || _currentEndpoint->type == Endpoint::Type::TCP_RELAY) if (_currentEndpoint->IsReflector())
{ {
currentEndpoint = preferredRelay; currentEndpoint = preferredRelay;
_currentEndpoint = _preferredRelay; _currentEndpoint = _preferredRelay;
@ -4176,8 +4169,8 @@ void VoIPController::SendRelayPings()
} }
if (_currentEndpoint->type == Endpoint::Type::UDP_RELAY && useUDP) if (_currentEndpoint->type == Endpoint::Type::UDP_RELAY && useUDP)
{ {
constexpr int64_t p2pID = (int64_t)(FOURCC('P', '2', 'P', '4')) << 32; constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '4')) << 32;
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32; constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
if (endpoints.find(p2pID) != endpoints.end()) if (endpoints.find(p2pID) != endpoints.end())
{ {
@ -4359,7 +4352,7 @@ void VoIPController::UpdateAudioBitrate()
for (pair<const int64_t, Endpoint> &_e : endpoints) for (pair<const int64_t, Endpoint> &_e : endpoints)
{ {
Endpoint &e = _e.second; Endpoint &e = _e.second;
if (e.type == Endpoint::Type::UDP_P2P_INET || e.type == Endpoint::Type::UDP_P2P_LAN) if (e.IsP2P())
{ {
e.averageRTT = 0; e.averageRTT = 0;
e.rtts.Reset(); e.rtts.Reset();
@ -4511,14 +4504,15 @@ void VoIPController::SendPublicEndpointsRequest()
publicEndpointsReqCount++; publicEndpointsReqCount++;
if (publicEndpointsReqCount < 10) if (publicEndpointsReqCount < 10)
{ {
messageThread.Post([this] { messageThread.Post(
if (waitingForRelayPeerInfo) [this] {
{ if (waitingForRelayPeerInfo)
LOGW("Resending peer relay info request"); {
SendPublicEndpointsRequest(); LOGW("Resending peer relay info request");
} SendPublicEndpointsRequest();
}, }
5.0); },
5.0);
} }
else else
{ {
@ -4565,125 +4559,3 @@ void VoIPController::TickJitterBufferAndCongestionControl()
} }
} }
} }
#pragma mark - Endpoint
Endpoint::Endpoint(int64_t id, uint16_t port, const IPv4Address &_address, const IPv6Address &_v6address, Type type, unsigned char peerTag[16]) : address(NetworkAddress::IPv4(_address.addr)), v6address(NetworkAddress::IPv6(_v6address.addr))
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint(int64_t id, uint16_t port, const NetworkAddress _address, const NetworkAddress _v6address, Type type, unsigned char peerTag[16]) : address(_address), v6address(_v6address)
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint() : address(NetworkAddress::Empty()), v6address(NetworkAddress::Empty())
{
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
const NetworkAddress &Endpoint::GetAddress() const
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
NetworkAddress &Endpoint::GetAddress()
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
bool Endpoint::IsIPv6Only() const
{
return address.IsEmpty() && !v6address.IsEmpty();
}
int64_t Endpoint::CleanID() const
{
int64_t _id = id;
if (type == Type::TCP_RELAY)
{
_id = _id ^ ((int64_t)FOURCC('T', 'C', 'P', ' ') << 32);
}
if (IsIPv6Only())
{
_id = _id ^ ((int64_t)FOURCC('I', 'P', 'v', '6') << 32);
}
return _id;
}
Endpoint::~Endpoint()
{
if (socket)
{
socket->Close();
}
}
#pragma mark - AudioInputTester
AudioInputTester::AudioInputTester(std::string deviceID) : deviceID(std::move(deviceID))
{
io = audio::AudioIO::Create(deviceID, "default");
if (io->Failed())
{
LOGE("Audio IO failed");
return;
}
input = io->GetInput();
input->SetCallback([](unsigned char *data, size_t size, void *ctx) -> size_t {
reinterpret_cast<AudioInputTester *>(ctx)->Update(reinterpret_cast<int16_t *>(data), size / 2);
return 0;
},
this);
input->Start();
}
AudioInputTester::~AudioInputTester()
{
input->Stop();
delete io;
}
void AudioInputTester::Update(int16_t *samples, size_t count)
{
for (size_t i = 0; i < count; i++)
{
int16_t s = abs(samples[i]);
if (s > maxSample)
maxSample = s;
}
}
float AudioInputTester::GetAndResetLevel()
{
float s = maxSample;
maxSample = 0;
return s / (float)INT16_MAX;
}

View File

@ -4,8 +4,7 @@
// you should have received with this source code distribution. // you should have received with this source code distribution.
// //
#ifndef __VOIPCONTROLLER_H #pragma once
#define __VOIPCONTROLLER_H
#ifndef _WIN32 #ifndef _WIN32
#include <arpa/inet.h> #include <arpa/inet.h>
@ -27,10 +26,12 @@
#include <atomic> #include <atomic>
#include "video/ScreamCongestionController.h" #include "video/ScreamCongestionController.h"
#include "audio/AudioInput.h" #include "audio/AudioInput.h"
#include "audio/Device.h"
#include "tools/BlockingQueue.h" #include "tools/BlockingQueue.h"
#include "audio/AudioOutput.h" #include "audio/AudioOutput.h"
#include "audio/AudioIO.h" #include "audio/AudioIO.h"
#include "controller/net/JitterBuffer.h" #include "controller/net/JitterBuffer.h"
#include "controller/net/Endpoint.h"
#include "controller/audio/OpusDecoder.h" #include "controller/audio/OpusDecoder.h"
#include "controller/audio/OpusEncoder.h" #include "controller/audio/OpusEncoder.h"
#include "controller/audio/EchoCanceller.h" #include "controller/audio/EchoCanceller.h"
@ -124,95 +125,6 @@ struct CellularCarrierInfo
std::string countryCode; std::string countryCode;
}; };
// API compatibility
struct IPv4Address
{
IPv4Address(std::string addr) : addr(addr){};
std::string addr;
};
struct IPv6Address
{
IPv6Address(std::string addr) : addr(addr){};
std::string addr;
};
class Endpoint
{
friend class VoIPController;
friend class VoIPGroupController;
public:
enum Type
{
UDP_P2P_INET = 1,
UDP_P2P_LAN,
UDP_RELAY,
TCP_RELAY
};
Endpoint(int64_t id, uint16_t port, const IPv4Address &address, const IPv6Address &v6address, Type type, unsigned char *peerTag);
Endpoint(int64_t id, uint16_t port, const NetworkAddress address, const NetworkAddress v6address, Type type, unsigned char *peerTag);
Endpoint();
~Endpoint();
const NetworkAddress &GetAddress() const;
NetworkAddress &GetAddress();
bool IsIPv6Only() const;
int64_t CleanID() const;
int64_t id;
uint16_t port;
NetworkAddress address;
NetworkAddress v6address;
Type type;
unsigned char peerTag[16];
private:
double lastPingTime;
uint32_t lastPingSeq;
HistoricBuffer<double, 6> rtts;
HistoricBuffer<double, 4> selfRtts;
std::map<int64_t, double> udpPingTimes;
double averageRTT;
std::shared_ptr<NetworkSocket> socket;
int udpPongCount;
int totalUdpPings = 0;
int totalUdpPingReplies = 0;
};
class AudioDevice
{
public:
std::string id;
std::string displayName;
};
class AudioOutputDevice : public AudioDevice
{
};
class AudioInputDevice : public AudioDevice
{
};
class AudioInputTester
{
public:
AudioInputTester(const std::string deviceID);
~AudioInputTester();
TGVOIP_DISALLOW_COPY_AND_ASSIGN(AudioInputTester);
float GetAndResetLevel();
bool Failed()
{
return io && io->Failed();
}
private:
void Update(int16_t *samples, size_t count);
audio::AudioIO *io = NULL;
audio::AudioInput *input = NULL;
int16_t maxSample = 0;
std::string deviceID;
};
class PacketSender; class PacketSender;
namespace video namespace video
{ {
@ -638,7 +550,7 @@ private:
void KDF2(unsigned char *msgKey, size_t x, unsigned char *aesKey, unsigned char *aesIv); void KDF2(unsigned char *msgKey, size_t x, unsigned char *aesKey, unsigned char *aesIv);
void SendPublicEndpointsRequest(); void SendPublicEndpointsRequest();
void SendPublicEndpointsRequest(const Endpoint &relay); void SendPublicEndpointsRequest(const Endpoint &relay);
Endpoint &GetEndpointByType(int type); Endpoint &GetEndpointByType(const Endpoint::Type type);
void SendPacketReliably(unsigned char type, unsigned char *data, size_t len, double retryInterval, double timeout); void SendPacketReliably(unsigned char type, unsigned char *data, size_t len, double retryInterval, double timeout);
uint32_t GenerateOutSeq(); uint32_t GenerateOutSeq();
void ActuallySendPacket(NetworkPacket pkt, Endpoint &ep); void ActuallySendPacket(NetworkPacket pkt, Endpoint &ep);
@ -862,72 +774,5 @@ public:
#endif #endif
}; };
class VoIPGroupController : public VoIPController
{
public:
VoIPGroupController(int32_t timeDifference);
virtual ~VoIPGroupController();
void SetGroupCallInfo(unsigned char *encryptionKey, unsigned char *reflectorGroupTag, unsigned char *reflectorSelfTag, unsigned char *reflectorSelfSecret, unsigned char *reflectorSelfTagHash, int32_t selfUserID, NetworkAddress reflectorAddress, NetworkAddress reflectorAddressV6, uint16_t reflectorPort);
void AddGroupCallParticipant(int32_t userID, unsigned char *memberTagHash, unsigned char *serializedStreams, size_t streamsLength);
void RemoveGroupCallParticipant(int32_t userID);
float GetParticipantAudioLevel(int32_t userID);
virtual void SetMicMute(bool mute);
void SetParticipantVolume(int32_t userID, float volume);
void SetParticipantStreams(int32_t userID, unsigned char *serializedStreams, size_t length);
static size_t GetInitialStreams(unsigned char *buf, size_t size);
struct Callbacks : public VoIPController::Callbacks
{
void (*updateStreams)(VoIPGroupController *, unsigned char *, size_t);
void (*participantAudioStateChanged)(VoIPGroupController *, int32_t, bool);
};
void SetCallbacks(Callbacks callbacks);
virtual std::string GetDebugString();
virtual void SetNetworkType(int type);
protected:
virtual void ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcEndpoint);
virtual void SendInit();
virtual void SendUdpPing(Endpoint &endpoint);
virtual void SendRelayPings();
virtual void SendPacket(unsigned char *data, size_t len, Endpoint &ep, PendingOutgoingPacket &srcPacket);
virtual void WritePacketHeader(uint32_t seq, BufferOutputStream *s, unsigned char type, uint32_t length, PacketSender *sender = NULL);
virtual void OnAudioOutputReady();
private:
int32_t GetCurrentUnixtime();
std::vector<std::shared_ptr<Stream>> DeserializeStreams(BufferInputStream &in);
void SendRecentPacketsRequest();
void SendSpecialReflectorRequest(unsigned char *data, size_t len);
void SerializeAndUpdateOutgoingStreams();
struct GroupCallParticipant
{
int32_t userID;
unsigned char memberTagHash[32];
std::vector<std::shared_ptr<Stream>> streams;
AudioLevelMeter *levelMeter;
};
std::vector<GroupCallParticipant> participants;
unsigned char reflectorSelfTag[16];
unsigned char reflectorSelfSecret[16];
unsigned char reflectorSelfTagHash[32];
int32_t userSelfID;
Endpoint groupReflector;
AudioMixer *audioMixer;
AudioLevelMeter selfLevelMeter;
Callbacks groupCallbacks;
struct PacketIdMapping
{
uint32_t seq;
uint16_t id;
double ackTime;
};
std::vector<PacketIdMapping> recentSentPackets;
Mutex sentPacketsMutex;
Mutex participantsMutex;
int32_t timeDifference;
};
}; // namespace tgvoip }; // namespace tgvoip
#endif

View File

@ -4,7 +4,7 @@
// you should have received with this source code distribution. // you should have received with this source code distribution.
// //
#include "VoIPController.h" #include "VoIPGroupController.h"
#include "tools/logging.h" #include "tools/logging.h"
#include "VoIPServerConfig.h" #include "VoIPServerConfig.h"
#include "controller/PrivateDefines.h" #include "controller/PrivateDefines.h"

75
VoIPGroupController.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
#include "VoIPController.h"
#include "controller/net/Endpoint.h"
#include "controller/net/NetworkSocket.h"
namespace tgvoip
{
class VoIPGroupController : public VoIPController
{
public:
VoIPGroupController(int32_t timeDifference);
virtual ~VoIPGroupController();
void SetGroupCallInfo(unsigned char *encryptionKey, unsigned char *reflectorGroupTag, unsigned char *reflectorSelfTag, unsigned char *reflectorSelfSecret, unsigned char *reflectorSelfTagHash, int32_t selfUserID, NetworkAddress reflectorAddress, NetworkAddress reflectorAddressV6, uint16_t reflectorPort);
void AddGroupCallParticipant(int32_t userID, unsigned char *memberTagHash, unsigned char *serializedStreams, size_t streamsLength);
void RemoveGroupCallParticipant(int32_t userID);
float GetParticipantAudioLevel(int32_t userID);
virtual void SetMicMute(bool mute);
void SetParticipantVolume(int32_t userID, float volume);
void SetParticipantStreams(int32_t userID, unsigned char *serializedStreams, size_t length);
static size_t GetInitialStreams(unsigned char *buf, size_t size);
struct Callbacks : public VoIPController::Callbacks
{
void (*updateStreams)(VoIPGroupController *, unsigned char *, size_t);
void (*participantAudioStateChanged)(VoIPGroupController *, int32_t, bool);
};
void SetCallbacks(Callbacks callbacks);
virtual std::string GetDebugString();
virtual void SetNetworkType(int type);
protected:
virtual void ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcEndpoint);
virtual void SendInit();
virtual void SendUdpPing(Endpoint &endpoint);
virtual void SendRelayPings();
virtual void SendPacket(unsigned char *data, size_t len, Endpoint &ep, PendingOutgoingPacket &srcPacket);
virtual void WritePacketHeader(uint32_t seq, BufferOutputStream *s, unsigned char type, uint32_t length, PacketSender *sender = NULL);
virtual void OnAudioOutputReady();
private:
int32_t GetCurrentUnixtime();
std::vector<std::shared_ptr<Stream>> DeserializeStreams(BufferInputStream &in);
void SendRecentPacketsRequest();
void SendSpecialReflectorRequest(unsigned char *data, size_t len);
void SerializeAndUpdateOutgoingStreams();
struct GroupCallParticipant
{
int32_t userID;
unsigned char memberTagHash[32];
std::vector<std::shared_ptr<Stream>> streams;
AudioLevelMeter *levelMeter;
};
std::vector<GroupCallParticipant> participants;
unsigned char reflectorSelfTag[16];
unsigned char reflectorSelfSecret[16];
unsigned char reflectorSelfTagHash[32];
int32_t userSelfID;
Endpoint groupReflector;
AudioMixer *audioMixer;
AudioLevelMeter selfLevelMeter;
Callbacks groupCallbacks;
struct PacketIdMapping
{
uint32_t seq;
uint16_t id;
double ackTime;
};
std::vector<PacketIdMapping> recentSentPackets;
Mutex sentPacketsMutex;
Mutex participantsMutex;
int32_t timeDifference;
};
} // namespace tgvoip

View File

@ -0,0 +1,44 @@
#include "AudioInputTester.h"
#include "../tools/logging.h"
using namespace tgvoip;
AudioInputTester::AudioInputTester(std::string deviceID) : deviceID(std::move(deviceID))
{
io = audio::AudioIO::Create(deviceID, "default");
if (io->Failed())
{
LOGE("Audio IO failed");
return;
}
input = io->GetInput();
input->SetCallback([](unsigned char *data, size_t size, void *ctx) -> size_t {
reinterpret_cast<AudioInputTester *>(ctx)->Update(reinterpret_cast<int16_t *>(data), size / 2);
return 0;
},
this);
input->Start();
}
AudioInputTester::~AudioInputTester()
{
input->Stop();
delete io;
}
void AudioInputTester::Update(int16_t *samples, size_t count)
{
for (size_t i = 0; i < count; i++)
{
int16_t s = abs(samples[i]);
if (s > maxSample)
maxSample = s;
}
}
float AudioInputTester::GetAndResetLevel()
{
float s = maxSample;
maxSample = 0;
return s / (float)INT16_MAX;
}

30
audio/AudioInputTester.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <string>
#include "../controller/PrivateDefines.h"
#include "AudioIO.h"
#include "AudioInput.h"
namespace tgvoip
{
class AudioInputTester
{
public:
AudioInputTester(const std::string deviceID);
~AudioInputTester();
TGVOIP_DISALLOW_COPY_AND_ASSIGN(AudioInputTester);
float GetAndResetLevel();
bool Failed()
{
return io && io->Failed();
}
private:
void Update(int16_t *samples, size_t count);
audio::AudioIO *io = NULL;
audio::AudioInput *input = NULL;
int16_t maxSample = 0;
std::string deviceID;
};
} // namespace tgvoip

22
audio/Device.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <string>
namespace tgvoip
{
class AudioDevice
{
public:
std::string id;
std::string displayName;
};
class AudioOutputDevice : public AudioDevice
{
};
class AudioInputDevice : public AudioDevice
{
};
} // namespace tgvoip

View File

@ -43,7 +43,7 @@ protected:
return controller->connectionInitTime; return controller->connectionInitTime;
} }
const HistoricBuffer<double, 32> &RTTHistory() const HistoricBuffer<double, 32> &RTTHistory() const
{ {
return controller->rttHistory; return controller->rttHistory;
} }
@ -53,7 +53,7 @@ protected:
return controller->messageThread; return controller->messageThread;
} }
const VoIPController::ProtocolInfo &GetProtocolInfo() const VoIPController::ProtocolInfo &GetProtocolInfo() const
{ {
return controller->protocolInfo; return controller->protocolInfo;
} }
@ -63,7 +63,7 @@ protected:
controller->SendStreamFlags(stm); controller->SendStreamFlags(stm);
} }
const VoIPController::Config &GetConfig() const VoIPController::Config &GetConfig() const
{ {
return controller->config; return controller->config;
} }

View File

@ -4,28 +4,18 @@
// you should have received with this source code distribution. // you should have received with this source code distribution.
// //
#include "controller/net/CongestionControl.h" #include "CongestionControl.h"
#include "VoIPController.h" #include "VoIPController.h"
#include "tools/logging.h" #include "tools/logging.h"
#include "VoIPServerConfig.h" #include "VoIPServerConfig.h"
#include "controller/PrivateDefines.h" #include "../PrivateDefines.h"
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
using namespace tgvoip; using namespace tgvoip;
CongestionControl::CongestionControl() CongestionControl::CongestionControl() : cwnd(static_cast<size_t>(ServerConfig::GetSharedInstance()->GetInt("audio_congestion_window", 1024)))
{ {
memset(inflightPackets, 0, sizeof(inflightPackets));
tmpRtt = 0;
tmpRttCount = 0;
lastSentSeq = 0;
lastActionTime = 0;
lastActionRtt = 0;
stateTransitionTime = 0;
inflightDataSize = 0;
lossCount = 0;
cwnd = (size_t)ServerConfig::GetSharedInstance()->GetInt("audio_congestion_window", 1024);
} }
CongestionControl::~CongestionControl() CongestionControl::~CongestionControl()
@ -59,14 +49,14 @@ double CongestionControl::GetMinimumRTT()
void CongestionControl::PacketAcknowledged(uint32_t seq) void CongestionControl::PacketAcknowledged(uint32_t seq)
{ {
for (int i = 0; i < 100; i++) for (auto &packet : inflightPackets)
{ {
if (inflightPackets[i].seq == seq && inflightPackets[i].sendTime > 0) if (packet.seq == seq && packet.sendTime > 0)
{ {
tmpRtt += (VoIPController::GetCurrentTime() - inflightPackets[i].sendTime); tmpRtt += (VoIPController::GetCurrentTime() - packet.sendTime);
tmpRttCount++; tmpRttCount++;
inflightPackets[i].sendTime = 0; packet.sendTime = 0;
inflightDataSize -= inflightPackets[i].size; inflightDataSize -= packet.size;
break; break;
} }
} }
@ -82,8 +72,7 @@ void CongestionControl::PacketSent(uint32_t seq, size_t size)
lastSentSeq = seq; lastSentSeq = seq;
double smallestSendTime = INFINITY; double smallestSendTime = INFINITY;
tgvoip_congestionctl_packet_t *slot = NULL; tgvoip_congestionctl_packet_t *slot = NULL;
int i; for (size_t i = 0; i < inflightPackets.size(); i++)
for (i = 0; i < 100; i++)
{ {
if (inflightPackets[i].sendTime == 0) if (inflightPackets[i].sendTime == 0)
{ {
@ -111,12 +100,12 @@ void CongestionControl::PacketSent(uint32_t seq, size_t size)
void CongestionControl::PacketLost(uint32_t seq) void CongestionControl::PacketLost(uint32_t seq)
{ {
for (int i = 0; i < 100; i++) for (auto &packet : inflightPackets)
{ {
if (inflightPackets[i].seq == seq && inflightPackets[i].sendTime > 0) if (packet.seq == seq && packet.sendTime > 0)
{ {
inflightPackets[i].sendTime = 0; packet.sendTime = 0;
inflightDataSize -= inflightPackets[i].size; inflightDataSize -= packet.size;
lossCount++; lossCount++;
break; break;
} }
@ -132,15 +121,14 @@ void CongestionControl::Tick()
tmpRtt = 0; tmpRtt = 0;
tmpRttCount = 0; tmpRttCount = 0;
} }
int i; for (auto &packet : inflightPackets)
for (i = 0; i < 100; i++)
{ {
if (inflightPackets[i].sendTime != 0 && VoIPController::GetCurrentTime() - inflightPackets[i].sendTime > 2) if (packet.sendTime != 0 && VoIPController::GetCurrentTime() - packet.sendTime > TGVOIP_CONCTL_LOST_AFTER)
{ {
inflightPackets[i].sendTime = 0; packet.sendTime = 0;
inflightDataSize -= inflightPackets[i].size; inflightDataSize -= packet.size;
lossCount++; lossCount++;
LOGD("Packet with seq %u was not acknowledged", inflightPackets[i].seq); LOGD("Packet with seq %u was not acknowledged", packet.seq);
} }
} }
inflightHistory.Add(inflightDataSize); inflightHistory.Add(inflightDataSize);
@ -150,6 +138,7 @@ int CongestionControl::GetBandwidthControlAction()
{ {
if (VoIPController::GetCurrentTime() - lastActionTime < 1) if (VoIPController::GetCurrentTime() - lastActionTime < 1)
return TGVOIP_CONCTL_ACT_NONE; return TGVOIP_CONCTL_ACT_NONE;
size_t inflightAvg = GetInflightDataSize(); size_t inflightAvg = GetInflightDataSize();
size_t max = cwnd + cwnd / 10; size_t max = cwnd + cwnd / 10;
size_t min = cwnd - cwnd / 10; size_t min = cwnd - cwnd / 10;

View File

@ -16,6 +16,8 @@
#define TGVOIP_CONCTL_ACT_DECREASE 2 #define TGVOIP_CONCTL_ACT_DECREASE 2
#define TGVOIP_CONCTL_ACT_NONE 0 #define TGVOIP_CONCTL_ACT_NONE 0
#define TGVOIP_CONCTL_LOST_AFTER 2
namespace tgvoip namespace tgvoip
{ {
@ -49,16 +51,16 @@ public:
private: private:
HistoricBuffer<double, 100> rttHistory; HistoricBuffer<double, 100> rttHistory;
HistoricBuffer<size_t, 30> inflightHistory; HistoricBuffer<size_t, 30> inflightHistory;
tgvoip_congestionctl_packet_t inflightPackets[100]; std::array<tgvoip_congestionctl_packet_t, 100> inflightPackets{};
uint32_t lossCount; uint32_t lossCount = 0;
double tmpRtt; double tmpRtt = 0.0;
double lastActionTime; double lastActionTime = 0;
double lastActionRtt; double lastActionRtt = 0;
double stateTransitionTime; double stateTransitionTime = 0;
int tmpRttCount; uint32_t tmpRttCount = 0;
uint32_t lastSentSeq; uint32_t lastSentSeq = 0;
uint32_t tickCount; uint32_t tickCount = 0;
size_t inflightDataSize; size_t inflightDataSize = 0;
size_t cwnd; size_t cwnd;
}; };
} // namespace tgvoip } // namespace tgvoip

View File

@ -0,0 +1,87 @@
//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//
#include "Endpoint.h"
#include "../../VoIPServerConfig.h"
#include "../PrivateDefines.h"
using namespace tgvoip;
Endpoint::Endpoint(int64_t id, uint16_t port, const IPv4Address &_address, const IPv6Address &_v6address, Type type, unsigned char peerTag[16]) : address(NetworkAddress::IPv4(_address.addr)), v6address(NetworkAddress::IPv6(_v6address.addr))
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint(int64_t id, uint16_t port, const NetworkAddress _address, const NetworkAddress _v6address, Type type, unsigned char peerTag[16]) : address(_address), v6address(_v6address)
{
this->id = id;
this->port = port;
this->type = type;
memcpy(this->peerTag, peerTag, 16);
if (type == Type::UDP_RELAY && ServerConfig::GetSharedInstance()->GetBoolean("force_tcp", false))
this->type = Type::TCP_RELAY;
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
Endpoint::Endpoint() : address(NetworkAddress::Empty()), v6address(NetworkAddress::Empty())
{
lastPingSeq = 0;
lastPingTime = 0;
averageRTT = 0;
socket = NULL;
udpPongCount = 0;
}
const NetworkAddress &Endpoint::GetAddress() const
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
NetworkAddress &Endpoint::GetAddress()
{
return IsIPv6Only() ? (NetworkAddress &)v6address : (NetworkAddress &)address;
}
bool Endpoint::IsIPv6Only() const
{
return address.IsEmpty() && !v6address.IsEmpty();
}
int64_t Endpoint::CleanID() const
{
int64_t _id = id;
if (type == Type::TCP_RELAY)
{
_id = _id ^ ((int64_t)FOURCC('T', 'C', 'P', ' ') << 32);
}
if (IsIPv6Only())
{
_id = _id ^ ((int64_t)FOURCC('I', 'P', 'v', '6') << 32);
}
return _id;
}
Endpoint::~Endpoint()
{
if (socket)
{
socket->Close();
}
}

67
controller/net/Endpoint.h Normal file
View File

@ -0,0 +1,67 @@
//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//
#pragma once
#include "NetworkSocket.h"
#include <map>
#include <memory>
namespace tgvoip
{
class VoIPGroupController;
class VoIPController;
class Endpoint
{
friend class VoIPController;
friend class VoIPGroupController;
public:
enum Type
{
UDP_P2P_INET = 1,
UDP_P2P_LAN,
UDP_RELAY,
TCP_RELAY
};
Endpoint(int64_t id, uint16_t port, const IPv4Address &address, const IPv6Address &v6address, Type type, unsigned char *peerTag);
Endpoint(int64_t id, uint16_t port, const NetworkAddress address, const NetworkAddress v6address, Type type, unsigned char *peerTag);
Endpoint();
~Endpoint();
const NetworkAddress &GetAddress() const;
NetworkAddress &GetAddress();
bool IsIPv6Only() const;
int64_t CleanID() const;
int64_t id;
uint16_t port;
NetworkAddress address;
NetworkAddress v6address;
Type type;
unsigned char peerTag[16];
const bool IsP2P() const
{
return type == UDP_P2P_INET || type == UDP_P2P_LAN;
}
const bool IsReflector() const
{
return type == UDP_RELAY || type == TCP_RELAY;
}
private:
double lastPingTime;
uint32_t lastPingSeq;
HistoricBuffer<double, 6> rtts;
HistoricBuffer<double, 4> selfRtts;
std::map<int64_t, double> udpPingTimes;
double averageRTT;
std::shared_ptr<NetworkSocket> socket;
int udpPongCount;
int totalUdpPings = 0;
int totalUdpPingReplies = 0;
};
} // namespace tgvoip

View File

@ -16,6 +16,20 @@
namespace tgvoip namespace tgvoip
{ {
// API compatibility
struct IPv4Address
{
IPv4Address(std::string addr) : addr(addr){};
std::string addr;
};
struct IPv6Address
{
IPv6Address(std::string addr) : addr(addr){};
std::string addr;
};
enum class NetworkProtocol enum class NetworkProtocol
{ {
UDP = 0, UDP = 0,

View File

@ -676,6 +676,7 @@ bool NetworkSocketPosix::Select(std::vector<NetworkSocket *> &readFds, std::vect
} }
else if (anyFailed) else if (anyFailed)
{ {
LOGE("Select failed, zeroing out");
FD_ZERO(&readSet); FD_ZERO(&readSet);
FD_ZERO(&writeSet); FD_ZERO(&writeSet);
} }

View File

@ -16,6 +16,7 @@
#include <numeric> #include <numeric>
#include <array> #include <array>
#include <limits> #include <limits>
#include <algorithm>
#include <bitset> #include <bitset>
#include <stddef.h> #include <stddef.h>
#include "tools/threading.h" #include "tools/threading.h"
@ -256,7 +257,6 @@ class HistoricBuffer
public: public:
HistoricBuffer() HistoricBuffer()
{ {
std::fill(data.begin(), data.end(), static_cast<T>(0));
} }
AVG_T Average() const AVG_T Average() const
@ -267,7 +267,7 @@ public:
AVG_T Average(size_t firstN) const AVG_T Average(size_t firstN) const
{ {
AVG_T avg = static_cast<AVG_T>(0); AVG_T avg = static_cast<AVG_T>(0);
for (size_t i = 0; i < firstN; i++) for (size_t i = 0; i < firstN; i++) // Manual iteration required to wrap around array with specific offset
{ {
avg += (*this)[i]; avg += (*this)[i];
} }
@ -299,24 +299,12 @@ public:
T Min() const T Min() const
{ {
T min = std::numeric_limits<T>::max(); return *std::min_element(data.begin(), data.end());
for (T i : data)
{
if (i < min)
min = i;
}
return min;
} }
T Max() const T Max() const
{ {
T max = std::numeric_limits<T>::min(); return *std::max_element(data.begin(), data.end());
for (T i : data)
{
if (i > max)
max = i;
}
return max;
} }
void Reset() void Reset()
@ -330,8 +318,8 @@ public:
assert(i < size); assert(i < size);
// [0] should return the most recent entry, [1] the one before it, and so on // [0] should return the most recent entry, [1] the one before it, and so on
ptrdiff_t _i = offset - i - 1; ptrdiff_t _i = offset - i - 1;
if (_i < 0) if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i; // wtf _i = size + _i;
return data[_i]; return data[_i];
} }
@ -340,8 +328,8 @@ public:
assert(i < size); assert(i < size);
// [0] should return the most recent entry, [1] the one before it, and so on // [0] should return the most recent entry, [1] the one before it, and so on
ptrdiff_t _i = offset - i - 1; ptrdiff_t _i = offset - i - 1;
if (_i < 0) if (_i < 0) // Wrap around offset a-la posmod
_i = size + _i; // wtf _i = size + _i;
return data[_i]; return data[_i];
} }
@ -351,7 +339,7 @@ public:
} }
private: private:
std::array<T, size> data; std::array<T, size> data{};
ptrdiff_t offset = 0; ptrdiff_t offset = 0;
}; };