mirror of
https://github.com/danog/libtgvoip.git
synced 2024-11-26 12:14:39 +01:00
Cleanup classes a bit, preparing for my strategy
This commit is contained in:
parent
8bfbecb8f5
commit
d2979cb7bb
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,3 +27,4 @@ autom4te.cache/
|
||||
*.o
|
||||
*.Plo
|
||||
*.lo
|
||||
.vscode
|
||||
|
@ -14,6 +14,7 @@ tools/logging.cpp \
|
||||
controller/MediaStreamItf.cpp \
|
||||
tools/MessageThread.cpp \
|
||||
controller/net/NetworkSocket.cpp \
|
||||
controller/net/Endpoint.cpp \
|
||||
controller/audio/OpusDecoder.cpp \
|
||||
controller/audio/OpusEncoder.cpp \
|
||||
controller/PacketReassembler.cpp \
|
||||
@ -23,6 +24,7 @@ audio/AudioIO.cpp \
|
||||
audio/AudioInput.cpp \
|
||||
audio/AudioOutput.cpp \
|
||||
audio/Resampler.cpp \
|
||||
audio/AudioInputTester.cpp \
|
||||
os/posix/NetworkSocketPosix.cpp \
|
||||
video/VideoSource.cpp \
|
||||
video/VideoRenderer.cpp \
|
||||
@ -763,4 +765,4 @@ CXXFLAGS += -std=gnu++0x $(CFLAGS)
|
||||
if TARGET_OS_OSX
|
||||
OBJCFLAGS = $(CFLAGS)
|
||||
OBJCXXFLAGS += -std=gnu++0x $(CFLAGS)
|
||||
endif
|
||||
endif
|
||||
|
61
Makefile.in
61
Makefile.in
@ -813,16 +813,17 @@ am__libtgvoip_la_SOURCES_DIST = TgVoip.cpp VoIPController.cpp \
|
||||
controller/audio/EchoCanceller.cpp \
|
||||
controller/net/JitterBuffer.cpp tools/logging.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/OpusEncoder.cpp \
|
||||
controller/PacketReassembler.cpp VoIPGroupController.cpp \
|
||||
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
|
||||
audio/AudioOutput.cpp audio/Resampler.cpp \
|
||||
os/posix/NetworkSocketPosix.cpp video/VideoSource.cpp \
|
||||
video/VideoRenderer.cpp video/VideoPacketSender.cpp \
|
||||
video/VideoFEC.cpp video/ScreamCongestionController.cpp \
|
||||
tools/json11.cpp os/darwin/AudioInputAudioUnit.cpp \
|
||||
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
|
||||
video/VideoSource.cpp video/VideoRenderer.cpp \
|
||||
video/VideoPacketSender.cpp video/VideoFEC.cpp \
|
||||
video/ScreamCongestionController.cpp tools/json11.cpp \
|
||||
os/darwin/AudioInputAudioUnit.cpp \
|
||||
os/darwin/AudioOutputAudioUnit.cpp os/darwin/AudioUnitIO.cpp \
|
||||
os/darwin/AudioInputAudioUnitOSX.cpp \
|
||||
os/darwin/AudioOutputAudioUnitOSX.cpp \
|
||||
@ -1750,19 +1751,20 @@ am__objects_12 = TgVoip.lo VoIPController.lo tools/Buffers.lo \
|
||||
controller/audio/EchoCanceller.lo \
|
||||
controller/net/JitterBuffer.lo tools/logging.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/OpusEncoder.lo \
|
||||
controller/PacketReassembler.lo VoIPGroupController.lo \
|
||||
VoIPServerConfig.lo audio/AudioIO.lo audio/AudioInput.lo \
|
||||
audio/AudioOutput.lo audio/Resampler.lo \
|
||||
os/posix/NetworkSocketPosix.lo video/VideoSource.lo \
|
||||
video/VideoRenderer.lo video/VideoPacketSender.lo \
|
||||
video/VideoFEC.lo video/ScreamCongestionController.lo \
|
||||
tools/json11.lo $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
|
||||
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
|
||||
$(am__objects_9) $(am__objects_10) $(am__objects_11)
|
||||
audio/AudioInputTester.lo os/posix/NetworkSocketPosix.lo \
|
||||
video/VideoSource.lo video/VideoRenderer.lo \
|
||||
video/VideoPacketSender.lo video/VideoFEC.lo \
|
||||
video/ScreamCongestionController.lo tools/json11.lo \
|
||||
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
|
||||
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
|
||||
$(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_11)
|
||||
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 \
|
||||
audio/$(DEPDIR)/AudioIO.Plo \
|
||||
audio/$(DEPDIR)/AudioIOCallback.Plo \
|
||||
audio/$(DEPDIR)/AudioInput.Plo audio/$(DEPDIR)/AudioOutput.Plo \
|
||||
audio/$(DEPDIR)/Resampler.Plo \
|
||||
audio/$(DEPDIR)/AudioInput.Plo \
|
||||
audio/$(DEPDIR)/AudioInputTester.Plo \
|
||||
audio/$(DEPDIR)/AudioOutput.Plo audio/$(DEPDIR)/Resampler.Plo \
|
||||
controller/$(DEPDIR)/MediaStreamItf.Plo \
|
||||
controller/$(DEPDIR)/PacketReassembler.Plo \
|
||||
controller/audio/$(DEPDIR)/EchoCanceller.Plo \
|
||||
controller/audio/$(DEPDIR)/OpusDecoder.Plo \
|
||||
controller/audio/$(DEPDIR)/OpusEncoder.Plo \
|
||||
controller/net/$(DEPDIR)/CongestionControl.Plo \
|
||||
controller/net/$(DEPDIR)/Endpoint.Plo \
|
||||
controller/net/$(DEPDIR)/JitterBuffer.Plo \
|
||||
controller/net/$(DEPDIR)/NetworkSocket.Plo \
|
||||
os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo \
|
||||
@ -2376,19 +2380,20 @@ SRC = TgVoip.cpp VoIPController.cpp tools/Buffers.cpp \
|
||||
controller/audio/EchoCanceller.cpp \
|
||||
controller/net/JitterBuffer.cpp tools/logging.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/OpusEncoder.cpp \
|
||||
controller/PacketReassembler.cpp VoIPGroupController.cpp \
|
||||
VoIPServerConfig.cpp audio/AudioIO.cpp audio/AudioInput.cpp \
|
||||
audio/AudioOutput.cpp audio/Resampler.cpp \
|
||||
os/posix/NetworkSocketPosix.cpp video/VideoSource.cpp \
|
||||
video/VideoRenderer.cpp video/VideoPacketSender.cpp \
|
||||
video/VideoFEC.cpp video/ScreamCongestionController.cpp \
|
||||
tools/json11.cpp $(am__append_1) $(am__append_4) \
|
||||
$(am__append_6) $(am__append_10) $(am__append_12) \
|
||||
$(am__append_14) $(am__append_16) $(am__append_18) \
|
||||
$(am__append_21) $(am__append_22) $(am__append_23)
|
||||
audio/AudioInputTester.cpp os/posix/NetworkSocketPosix.cpp \
|
||||
video/VideoSource.cpp video/VideoRenderer.cpp \
|
||||
video/VideoPacketSender.cpp video/VideoFEC.cpp \
|
||||
video/ScreamCongestionController.cpp tools/json11.cpp \
|
||||
$(am__append_1) $(am__append_4) $(am__append_6) \
|
||||
$(am__append_10) $(am__append_12) $(am__append_14) \
|
||||
$(am__append_16) $(am__append_18) $(am__append_21) \
|
||||
$(am__append_22) $(am__append_23)
|
||||
TGVOIP_HDRS = TgVoip.h VoIPController.h tools/Buffers.h \
|
||||
tools/BlockingQueue.h controller/PrivateDefines.h \
|
||||
controller/net/CongestionControl.h \
|
||||
@ -2535,6 +2540,8 @@ tools/MessageThread.lo: tools/$(am__dirstamp) \
|
||||
tools/$(DEPDIR)/$(am__dirstamp)
|
||||
controller/net/NetworkSocket.lo: controller/net/$(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/$(DEPDIR)/$(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/Resampler.lo: audio/$(am__dirstamp) \
|
||||
audio/$(DEPDIR)/$(am__dirstamp)
|
||||
audio/AudioInputTester.lo: audio/$(am__dirstamp) \
|
||||
audio/$(DEPDIR)/$(am__dirstamp)
|
||||
os/posix/$(am__dirstamp):
|
||||
@$(MKDIR_P) os/posix
|
||||
@: > 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)/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)/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)/Resampler.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)/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)/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)/NetworkSocket.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)/AudioIOCallback.Plo
|
||||
-rm -f audio/$(DEPDIR)/AudioInput.Plo
|
||||
-rm -f audio/$(DEPDIR)/AudioInputTester.Plo
|
||||
-rm -f audio/$(DEPDIR)/AudioOutput.Plo
|
||||
-rm -f audio/$(DEPDIR)/Resampler.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)/OpusEncoder.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)/NetworkSocket.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)/AudioIOCallback.Plo
|
||||
-rm -f audio/$(DEPDIR)/AudioInput.Plo
|
||||
-rm -f audio/$(DEPDIR)/AudioInputTester.Plo
|
||||
-rm -f audio/$(DEPDIR)/AudioOutput.Plo
|
||||
-rm -f audio/$(DEPDIR)/Resampler.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)/OpusEncoder.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)/NetworkSocket.Plo
|
||||
-rm -f os/darwin/$(DEPDIR)/AudioInputAudioUnit.Plo
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "controller/audio/OpusDecoder.h"
|
||||
#include "VoIPServerConfig.h"
|
||||
#include "controller/PrivateDefines.h"
|
||||
#include "controller/net/Endpoint.h"
|
||||
#include "tools/json11.hpp"
|
||||
#include "controller/PacketSender.h"
|
||||
#include "video/VideoPacketSender.h"
|
||||
@ -425,7 +426,7 @@ void VoIPController::SetNetworkType(int type)
|
||||
if (_preferredRelay.type == Endpoint::Type::UDP_RELAY)
|
||||
currentEndpoint = preferredRelay;
|
||||
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);
|
||||
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();
|
||||
BufferInputStream in(packet.data);
|
||||
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");
|
||||
return;
|
||||
@ -2105,7 +2106,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
|
||||
in.Seek(16);
|
||||
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
|
||||
in.Seek(16 + 12);
|
||||
@ -2160,8 +2161,8 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
|
||||
uint32_t peerAddr = (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 lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32;
|
||||
constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '4')) << 32;
|
||||
constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
|
||||
|
||||
if (currentEndpoint == p2pID || currentEndpoint == lanID)
|
||||
currentEndpoint = preferredRelay;
|
||||
@ -2583,7 +2584,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
@ -3034,7 +3035,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
|
||||
LOGV("received lan endpoint");
|
||||
uint32_t peerAddr = (uint32_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];
|
||||
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)");
|
||||
uint32_t peerAddr = (uint32_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)
|
||||
currentEndpoint = preferredRelay;
|
||||
|
||||
@ -3268,7 +3269,7 @@ void VoIPController::ProcessExtraData(Buffer &data)
|
||||
peerIPv6Available = true;
|
||||
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;
|
||||
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)
|
||||
return;
|
||||
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);
|
||||
else if (peerVersion < 9)
|
||||
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());
|
||||
#endif
|
||||
|
||||
/*ActuallySendPacket(NetworkPacket{
|
||||
Buffer(std::move(out)),
|
||||
ep.GetAddress(),
|
||||
ep.port,
|
||||
ep.type==Endpoint::Type::TCP_RELAY ? NetworkProtocol::TCP : NetworkProtocol::UDP
|
||||
}, ep);*/
|
||||
rawSendQueue.Put(RawPendingOutgoingPacket{
|
||||
NetworkPacket{
|
||||
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});
|
||||
rawSendQueue.Put(
|
||||
RawPendingOutgoingPacket{
|
||||
NetworkPacket{
|
||||
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)
|
||||
@ -3556,21 +3552,18 @@ std::string VoIPController::GetPacketTypeString(unsigned char type)
|
||||
case PKT_STREAM_EC:
|
||||
return "stream_ec";
|
||||
}
|
||||
char buf[255];
|
||||
snprintf(buf, sizeof(buf), "unknown(%u)", type);
|
||||
return string(buf);
|
||||
return string("unknown(") + std::to_string(type) + ')';
|
||||
}
|
||||
|
||||
void VoIPController::AddIPv6Relays()
|
||||
{
|
||||
|
||||
if (!myIPv6.IsEmpty() && !didAddIPv6Relays)
|
||||
{
|
||||
unordered_map<string, vector<Endpoint>> endpointsByAddress;
|
||||
for (pair<const int64_t, Endpoint> &_e : endpoints)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -3582,7 +3575,7 @@ void VoIPController::AddIPv6Relays()
|
||||
{
|
||||
didAddIPv6Relays = true;
|
||||
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.lastPingSeq = 0;
|
||||
e.lastPingTime = 0;
|
||||
@ -3621,7 +3614,7 @@ void VoIPController::AddTCPRelays()
|
||||
tcpRelay.lastPingTime = 0;
|
||||
tcpRelay.rtts.Reset();
|
||||
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)
|
||||
{
|
||||
LOGV("Setting current endpoint to TCP");
|
||||
@ -3750,7 +3743,7 @@ void VoIPController::SendPublicEndpointsRequest(const Endpoint &relay)
|
||||
NetworkProtocol::UDP});
|
||||
}
|
||||
|
||||
Endpoint &VoIPController::GetEndpointByType(int type)
|
||||
Endpoint &VoIPController::GetEndpointByType(const Endpoint::Type type)
|
||||
{
|
||||
if (type == Endpoint::Type::UDP_RELAY && preferredRelay)
|
||||
return endpoints.at(preferredRelay);
|
||||
@ -4168,7 +4161,7 @@ void VoIPController::SendRelayPings()
|
||||
preferredRelay = minPingRelay->id;
|
||||
_preferredRelay = minPingRelay;
|
||||
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;
|
||||
@ -4176,8 +4169,8 @@ void VoIPController::SendRelayPings()
|
||||
}
|
||||
if (_currentEndpoint->type == Endpoint::Type::UDP_RELAY && useUDP)
|
||||
{
|
||||
constexpr int64_t p2pID = (int64_t)(FOURCC('P', '2', 'P', '4')) << 32;
|
||||
constexpr int64_t lanID = (int64_t)(FOURCC('L', 'A', 'N', '4')) << 32;
|
||||
constexpr int64_t p2pID = static_cast<int64_t>(FOURCC('P', '2', 'P', '4')) << 32;
|
||||
constexpr int64_t lanID = static_cast<int64_t>(FOURCC('L', 'A', 'N', '4')) << 32;
|
||||
|
||||
if (endpoints.find(p2pID) != endpoints.end())
|
||||
{
|
||||
@ -4359,7 +4352,7 @@ void VoIPController::UpdateAudioBitrate()
|
||||
for (pair<const int64_t, Endpoint> &_e : endpoints)
|
||||
{
|
||||
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.rtts.Reset();
|
||||
@ -4511,14 +4504,15 @@ void VoIPController::SendPublicEndpointsRequest()
|
||||
publicEndpointsReqCount++;
|
||||
if (publicEndpointsReqCount < 10)
|
||||
{
|
||||
messageThread.Post([this] {
|
||||
if (waitingForRelayPeerInfo)
|
||||
{
|
||||
LOGW("Resending peer relay info request");
|
||||
SendPublicEndpointsRequest();
|
||||
}
|
||||
},
|
||||
5.0);
|
||||
messageThread.Post(
|
||||
[this] {
|
||||
if (waitingForRelayPeerInfo)
|
||||
{
|
||||
LOGW("Resending peer relay info request");
|
||||
SendPublicEndpointsRequest();
|
||||
}
|
||||
},
|
||||
5.0);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
163
VoIPController.h
163
VoIPController.h
@ -4,8 +4,7 @@
|
||||
// you should have received with this source code distribution.
|
||||
//
|
||||
|
||||
#ifndef __VOIPCONTROLLER_H
|
||||
#define __VOIPCONTROLLER_H
|
||||
#pragma once
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
@ -27,10 +26,12 @@
|
||||
#include <atomic>
|
||||
#include "video/ScreamCongestionController.h"
|
||||
#include "audio/AudioInput.h"
|
||||
#include "audio/Device.h"
|
||||
#include "tools/BlockingQueue.h"
|
||||
#include "audio/AudioOutput.h"
|
||||
#include "audio/AudioIO.h"
|
||||
#include "controller/net/JitterBuffer.h"
|
||||
#include "controller/net/Endpoint.h"
|
||||
#include "controller/audio/OpusDecoder.h"
|
||||
#include "controller/audio/OpusEncoder.h"
|
||||
#include "controller/audio/EchoCanceller.h"
|
||||
@ -124,95 +125,6 @@ struct CellularCarrierInfo
|
||||
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;
|
||||
namespace video
|
||||
{
|
||||
@ -638,7 +550,7 @@ private:
|
||||
void KDF2(unsigned char *msgKey, size_t x, unsigned char *aesKey, unsigned char *aesIv);
|
||||
void SendPublicEndpointsRequest();
|
||||
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);
|
||||
uint32_t GenerateOutSeq();
|
||||
void ActuallySendPacket(NetworkPacket pkt, Endpoint &ep);
|
||||
@ -862,72 +774,5 @@ public:
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
// you should have received with this source code distribution.
|
||||
//
|
||||
|
||||
#include "VoIPController.h"
|
||||
#include "VoIPGroupController.h"
|
||||
#include "tools/logging.h"
|
||||
#include "VoIPServerConfig.h"
|
||||
#include "controller/PrivateDefines.h"
|
||||
|
75
VoIPGroupController.h
Normal file
75
VoIPGroupController.h
Normal 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
|
44
audio/AudioInputTester.cpp
Normal file
44
audio/AudioInputTester.cpp
Normal 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
30
audio/AudioInputTester.h
Normal 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
22
audio/Device.h
Normal 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
|
@ -43,7 +43,7 @@ protected:
|
||||
return controller->connectionInitTime;
|
||||
}
|
||||
|
||||
const HistoricBuffer<double, 32> &RTTHistory()
|
||||
const HistoricBuffer<double, 32> &RTTHistory() const
|
||||
{
|
||||
return controller->rttHistory;
|
||||
}
|
||||
@ -53,7 +53,7 @@ protected:
|
||||
return controller->messageThread;
|
||||
}
|
||||
|
||||
const VoIPController::ProtocolInfo &GetProtocolInfo()
|
||||
const VoIPController::ProtocolInfo &GetProtocolInfo() const
|
||||
{
|
||||
return controller->protocolInfo;
|
||||
}
|
||||
@ -63,7 +63,7 @@ protected:
|
||||
controller->SendStreamFlags(stm);
|
||||
}
|
||||
|
||||
const VoIPController::Config &GetConfig()
|
||||
const VoIPController::Config &GetConfig() const
|
||||
{
|
||||
return controller->config;
|
||||
}
|
||||
|
@ -4,28 +4,18 @@
|
||||
// you should have received with this source code distribution.
|
||||
//
|
||||
|
||||
#include "controller/net/CongestionControl.h"
|
||||
#include "CongestionControl.h"
|
||||
#include "VoIPController.h"
|
||||
#include "tools/logging.h"
|
||||
#include "VoIPServerConfig.h"
|
||||
#include "controller/PrivateDefines.h"
|
||||
#include "../PrivateDefines.h"
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
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()
|
||||
@ -59,14 +49,14 @@ double CongestionControl::GetMinimumRTT()
|
||||
|
||||
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++;
|
||||
inflightPackets[i].sendTime = 0;
|
||||
inflightDataSize -= inflightPackets[i].size;
|
||||
packet.sendTime = 0;
|
||||
inflightDataSize -= packet.size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -82,8 +72,7 @@ void CongestionControl::PacketSent(uint32_t seq, size_t size)
|
||||
lastSentSeq = seq;
|
||||
double smallestSendTime = INFINITY;
|
||||
tgvoip_congestionctl_packet_t *slot = NULL;
|
||||
int i;
|
||||
for (i = 0; i < 100; i++)
|
||||
for (size_t i = 0; i < inflightPackets.size(); i++)
|
||||
{
|
||||
if (inflightPackets[i].sendTime == 0)
|
||||
{
|
||||
@ -111,12 +100,12 @@ void CongestionControl::PacketSent(uint32_t seq, size_t size)
|
||||
|
||||
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;
|
||||
inflightDataSize -= inflightPackets[i].size;
|
||||
packet.sendTime = 0;
|
||||
inflightDataSize -= packet.size;
|
||||
lossCount++;
|
||||
break;
|
||||
}
|
||||
@ -132,15 +121,14 @@ void CongestionControl::Tick()
|
||||
tmpRtt = 0;
|
||||
tmpRttCount = 0;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < 100; i++)
|
||||
for (auto &packet : inflightPackets)
|
||||
{
|
||||
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;
|
||||
inflightDataSize -= inflightPackets[i].size;
|
||||
packet.sendTime = 0;
|
||||
inflightDataSize -= packet.size;
|
||||
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);
|
||||
@ -150,6 +138,7 @@ int CongestionControl::GetBandwidthControlAction()
|
||||
{
|
||||
if (VoIPController::GetCurrentTime() - lastActionTime < 1)
|
||||
return TGVOIP_CONCTL_ACT_NONE;
|
||||
|
||||
size_t inflightAvg = GetInflightDataSize();
|
||||
size_t max = cwnd + cwnd / 10;
|
||||
size_t min = cwnd - cwnd / 10;
|
||||
|
@ -16,6 +16,8 @@
|
||||
#define TGVOIP_CONCTL_ACT_DECREASE 2
|
||||
#define TGVOIP_CONCTL_ACT_NONE 0
|
||||
|
||||
#define TGVOIP_CONCTL_LOST_AFTER 2
|
||||
|
||||
namespace tgvoip
|
||||
{
|
||||
|
||||
@ -49,16 +51,16 @@ public:
|
||||
private:
|
||||
HistoricBuffer<double, 100> rttHistory;
|
||||
HistoricBuffer<size_t, 30> inflightHistory;
|
||||
tgvoip_congestionctl_packet_t inflightPackets[100];
|
||||
uint32_t lossCount;
|
||||
double tmpRtt;
|
||||
double lastActionTime;
|
||||
double lastActionRtt;
|
||||
double stateTransitionTime;
|
||||
int tmpRttCount;
|
||||
uint32_t lastSentSeq;
|
||||
uint32_t tickCount;
|
||||
size_t inflightDataSize;
|
||||
std::array<tgvoip_congestionctl_packet_t, 100> inflightPackets{};
|
||||
uint32_t lossCount = 0;
|
||||
double tmpRtt = 0.0;
|
||||
double lastActionTime = 0;
|
||||
double lastActionRtt = 0;
|
||||
double stateTransitionTime = 0;
|
||||
uint32_t tmpRttCount = 0;
|
||||
uint32_t lastSentSeq = 0;
|
||||
uint32_t tickCount = 0;
|
||||
size_t inflightDataSize = 0;
|
||||
size_t cwnd;
|
||||
};
|
||||
} // namespace tgvoip
|
||||
|
87
controller/net/Endpoint.cpp
Normal file
87
controller/net/Endpoint.cpp
Normal 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
67
controller/net/Endpoint.h
Normal 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
|
@ -16,6 +16,20 @@
|
||||
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
|
||||
{
|
||||
UDP = 0,
|
||||
|
@ -676,6 +676,7 @@ bool NetworkSocketPosix::Select(std::vector<NetworkSocket *> &readFds, std::vect
|
||||
}
|
||||
else if (anyFailed)
|
||||
{
|
||||
LOGE("Select failed, zeroing out");
|
||||
FD_ZERO(&readSet);
|
||||
FD_ZERO(&writeSet);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <numeric>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
#include <stddef.h>
|
||||
#include "tools/threading.h"
|
||||
@ -256,7 +257,6 @@ class HistoricBuffer
|
||||
public:
|
||||
HistoricBuffer()
|
||||
{
|
||||
std::fill(data.begin(), data.end(), static_cast<T>(0));
|
||||
}
|
||||
|
||||
AVG_T Average() const
|
||||
@ -267,7 +267,7 @@ public:
|
||||
AVG_T Average(size_t firstN) const
|
||||
{
|
||||
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];
|
||||
}
|
||||
@ -299,24 +299,12 @@ public:
|
||||
|
||||
T Min() const
|
||||
{
|
||||
T min = std::numeric_limits<T>::max();
|
||||
for (T i : data)
|
||||
{
|
||||
if (i < min)
|
||||
min = i;
|
||||
}
|
||||
return min;
|
||||
return *std::min_element(data.begin(), data.end());
|
||||
}
|
||||
|
||||
T Max() const
|
||||
{
|
||||
T max = std::numeric_limits<T>::min();
|
||||
for (T i : data)
|
||||
{
|
||||
if (i > max)
|
||||
max = i;
|
||||
}
|
||||
return max;
|
||||
return *std::max_element(data.begin(), data.end());
|
||||
}
|
||||
|
||||
void Reset()
|
||||
@ -330,8 +318,8 @@ public:
|
||||
assert(i < size);
|
||||
// [0] should return the most recent entry, [1] the one before it, and so on
|
||||
ptrdiff_t _i = offset - i - 1;
|
||||
if (_i < 0)
|
||||
_i = size + _i; // wtf
|
||||
if (_i < 0) // Wrap around offset a-la posmod
|
||||
_i = size + _i;
|
||||
return data[_i];
|
||||
}
|
||||
|
||||
@ -340,8 +328,8 @@ public:
|
||||
assert(i < size);
|
||||
// [0] should return the most recent entry, [1] the one before it, and so on
|
||||
ptrdiff_t _i = offset - i - 1;
|
||||
if (_i < 0)
|
||||
_i = size + _i; // wtf
|
||||
if (_i < 0) // Wrap around offset a-la posmod
|
||||
_i = size + _i;
|
||||
return data[_i];
|
||||
}
|
||||
|
||||
@ -351,7 +339,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<T, size> data;
|
||||
std::array<T, size> data{};
|
||||
ptrdiff_t offset = 0;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user