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

Full RAII

This commit is contained in:
Daniil Gentili 2020-01-24 20:26:34 +01:00
parent bcb8a6ad45
commit b2368a71d1
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
21 changed files with 329 additions and 451 deletions

View File

@ -32,11 +32,6 @@
#include <sstream>
#include <inttypes.h>
#include <float.h>
#ifdef HAVE_CONFIG_H
#include <opus/opus.h>
#else
#include <opus/opus.h>
#endif
inline int pad4(int x)
{
@ -79,84 +74,12 @@ extern FILE *tgvoipLogFile;
#pragma mark - Public API
VoIPController::VoIPController() : activeNetItfName(""),
currentAudioInput("default"),
currentAudioOutput("default"),
proxyAddress(""),
proxyUsername(""),
proxyPassword(""),
ecAudioPackets(4),
VoIPController::VoIPController() : ecAudioPackets(4),
rawSendQueue(64)
{
seq = 1;
lastRemoteSeq = 0;
state = STATE_WAIT_INIT;
audioInput = nullptr;
audioOutput = nullptr;
encoder = nullptr;
audioOutStarted = false;
audioTimestampIn = 0;
audioTimestampOut = 0;
stopping = false;
memset(&stats, 0, sizeof(TrafficStats));
lastRemoteAckSeq = 0;
lastSentSeq = 0;
recvLossCount = 0;
packetsReceived = 0;
waitingForAcks = false;
networkType = NET_TYPE_UNKNOWN;
echoCanceller = nullptr;
dontSendPackets = 0;
micMuted = false;
waitingForRelayPeerInfo = false;
allowP2p = true;
dataSavingMode = false;
publicEndpointsReqTime = 0;
connectionInitTime = 0;
lastRecvPacketTime = 0;
dataSavingRequestedByPeer = false;
peerVersion = 0;
conctl = new CongestionControl();
prevSendLossCount = 0;
receivedInit = false;
receivedInitAck = false;
statsDump = nullptr;
useTCP = false;
useUDP = true;
didAddTcpRelays = false;
udpPingCount = 0;
lastUdpPingTime = 0;
proxyProtocol = PROXY_NONE;
proxyPort = 0;
selectCanceller = SocketSelectCanceller::Create();
udpSocket = NetworkSocket::Create(NetworkProtocol::UDP);
realUdpSocket = udpSocket;
udpConnectivityState = UDP_UNKNOWN;
echoCancellationStrength = 1;
peerCapabilities = 0;
callbacks = {0};
didReceiveGroupCallKey = false;
didReceiveGroupCallKeyAck = false;
didSendGroupCallKey = false;
didSendUpgradeRequest = false;
didInvokeUpgradeCallback = false;
connectionMaxLayer = 0;
useMTProto2 = false;
setCurrentEndpointToTCP = false;
useIPv6 = false;
peerIPv6Available = false;
shittyInternetMode = false;
didAddIPv6Relays = false;
didSendIPv6Endpoint = false;
unsentStreamPackets.store(0);
runReceiver = false;
sendThread = nullptr;
recvThread = nullptr;
maxAudioBitrate = ServerConfig::GetSharedInstance()->GetUInt("audio_max_bitrate", 20000);
maxAudioBitrateGPRS = ServerConfig::GetSharedInstance()->GetUInt("audio_max_bitrate_gprs", 8000);
@ -180,10 +103,6 @@ VoIPController::VoIPController() : activeNetItfName(""),
maxUnsentStreamPackets = ServerConfig::GetSharedInstance()->GetUInt("max_unsent_stream_packets", 2);
unackNopThreshold = ServerConfig::GetSharedInstance()->GetUInt("unack_nop_threshold", 10);
#ifdef __APPLE__
machTimestart = 0;
#endif
shared_ptr<Stream> stm = make_shared<Stream>();
stm->id = 1;
stm->type = STREAM_TYPE_AUDIO;
@ -201,18 +120,7 @@ VoIPController::~VoIPController()
LOGE("!!!!!!!!!!!!!!!!!!!! CALL controller->Stop() BEFORE DELETING THE CONTROLLER OBJECT !!!!!!!!!!!!!!!!!!!!!!!1");
abort();
}
LOGD("before close socket");
if (udpSocket)
delete udpSocket;
if (udpSocket != realUdpSocket)
delete realUdpSocket;
LOGD("before delete audioIO");
if (audioIO)
{
delete audioIO;
audioInput = nullptr;
audioOutput = nullptr;
}
for (auto _stm = incomingStreams.begin(); _stm != incomingStreams.end(); ++_stm)
{
shared_ptr<Stream> stm = *_stm;
@ -222,22 +130,11 @@ VoIPController::~VoIPController()
stm->decoder->Stop();
}
}
LOGD("before delete encoder");
if (encoder)
{
encoder->Stop();
delete encoder;
}
LOGD("before delete echo canceller");
if (echoCanceller)
{
echoCanceller->Stop();
delete echoCanceller;
}
delete conctl;
if (statsDump)
fclose(statsDump);
delete selectCanceller;
LOGD("Left VoIPController::~VoIPController");
if (tgvoipLogFile)
{
@ -245,13 +142,6 @@ VoIPController::~VoIPController()
tgvoipLogFile = nullptr;
fclose(log);
}
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
if (preprocDecoder)
{
opus_decoder_destroy(preprocDecoder);
preprocDecoder = nullptr;
}
#endif
}
void VoIPController::Stop()
@ -273,13 +163,11 @@ void VoIPController::Stop()
if (sendThread)
{
sendThread->Join();
delete sendThread;
}
LOGD("before join recvThread");
if (recvThread)
{
recvThread->Join();
delete recvThread;
}
LOGD("before stop messageThread");
messageThread.Stop();
@ -297,12 +185,6 @@ void VoIPController::Stop()
audioOutput->SetCallback(NULL, NULL);
}
}
if (videoPacketSender)
{
LOGD("before delete video packet sender");
delete videoPacketSender;
videoPacketSender = nullptr;
}
LOGD("Left VoIPController::Stop [need rate = %d]", (int)needRate);
}
@ -356,7 +238,7 @@ void VoIPController::Start()
}
runReceiver = true;
recvThread = new Thread(bind(&VoIPController::RunRecvThread, this));
recvThread.reset(new Thread(bind(&VoIPController::RunRecvThread, this)));
recvThread->SetName("VoipRecv");
recvThread->Start();
@ -375,7 +257,7 @@ void VoIPController::Connect()
//InitializeTimers();
//SendInit();
sendThread = new Thread(bind(&VoIPController::RunSendThread, this));
sendThread.reset(new Thread(bind(&VoIPController::RunSendThread, this)));
sendThread->SetName("VoipSend");
sendThread->Start();
}
@ -611,8 +493,8 @@ string VoIPController::GetDebugString()
"Bytes sent/recvd: %llu/%llu",
jitterBuffer ? jitterBuffer->GetMinPacketCount() : 0, jitterBuffer ? jitterBuffer->GetAverageDelay() : 0, avgLate[0], avgLate[1], avgLate[2],
// (int)(GetAverageRTT()*1000), 0,
(int)(conctl->GetAverageRTT() * 1000), (int)(conctl->GetMinimumRTT() * 1000),
int(conctl->GetInflightDataSize()), int(conctl->GetCongestionWindow()),
(int)(conctl.GetAverageRTT() * 1000), (int)(conctl.GetMinimumRTT() * 1000),
int(conctl.GetInflightDataSize()), int(conctl.GetCongestionWindow()),
keyFingerprint[0], keyFingerprint[1], keyFingerprint[2], keyFingerprint[3], keyFingerprint[4], keyFingerprint[5], keyFingerprint[6], keyFingerprint[7],
useMTProto2 ? " (MTProto2.0)" : "",
lastSentSeq, lastRemoteAckSeq, lastRemoteSeq,
@ -717,7 +599,7 @@ string VoIPController::GetDebugLog()
{"network", network},
{"protocol_version", std::min(peerVersion, PROTOCOL_VERSION)},
{"total_losses", json11::Json::object{
{"s", (int32_t)conctl->GetSendLossCount()},
{"s", (int32_t)conctl.GetSendLossCount()},
{"r", (int32_t)recvLossCount}
}},
{"call_duration", GetCurrentTime()-connectionInitTime},
@ -798,7 +680,7 @@ string VoIPController::GetDebugLog()
{"packet_stats", json11::Json::object{
{"out", (int)seq},
{"in", (int)packetsReceived},
{"lost_out", (int)conctl->GetSendLossCount()},
{"lost_out", (int)conctl.GetSendLossCount()},
{"lost_in", (int)recvLossCount}}},
{"endpoints", _endpoints},
{"problems", problems}})
@ -937,7 +819,6 @@ void VoIPController::SetAudioDataCallbacks(std::function<void(int16_t *, size_t)
audioInputDataCallback = input;
audioOutputDataCallback = output;
audioPreprocDataCallback = preproc;
preprocDecoder = preprocDecoder ? preprocDecoder : opus_decoder_create(48000, 1, NULL);
}
#endif
@ -970,29 +851,15 @@ void VoIPController::SetConfig(const Config &cfg)
{
tgvoipLogFile = nullptr;
}
if (statsDump)
{
fclose(statsDump);
statsDump = nullptr;
}
if (!config.statsDumpFilePath.empty())
{
#ifndef _WIN32
statsDump = fopen(config.statsDumpFilePath.c_str(), "w");
#else
if (_wfopen_s(&statsDump, config.statsDumpFilePath.c_str(), L"w") != 0)
{
statsDump = nullptr;
}
#endif
statsDump.open(config.statsDumpFilePath);
if (statsDump)
fprintf(statsDump, "Time\tRTT\tLRSeq\tLSSeq\tLASeq\tLostR\tLostS\tCWnd\tBitrate\tLoss%%\tJitter\tJDelay\tAJDelay\n");
//else
// LOGW("Failed to open stats dump file %s for writing", config.statsDumpFilePath.c_str());
statsDump << "Time\tRTT\tLRSeq\tLSSeq\tLASeq\tLostR\tLostS\tCWnd\tBitrate\tLoss%%\tJitter\tJDelay\tAJDelay\n";
}
else
{
statsDump = nullptr;
statsDump.close();
}
UpdateDataSavingState();
UpdateAudioBitrateLimit();
@ -1045,19 +912,19 @@ vector<uint8_t> VoIPController::GetPersistentState()
void VoIPController::SetOutputVolume(float level)
{
outputVolume.SetLevel(level);
outputVolume->SetLevel(level);
}
void VoIPController::SetInputVolume(float level)
{
inputVolume.SetLevel(level);
inputVolume->SetLevel(level);
}
#if defined(__APPLE__) && TARGET_OS_OSX
void VoIPController::SetAudioOutputDuckingEnabled(bool enabled)
{
macAudioDuckingEnabled = enabled;
audio::AudioUnitIO *osxAudio = dynamic_cast<audio::AudioUnitIO *>(audioIO);
audio::AudioUnitIO *osxAudio = dynamic_cast<audio::AudioUnitIO *>(audioIO.get());
if (osxAudio)
{
osxAudio->SetDuckingEnabled(enabled);
@ -1084,21 +951,20 @@ void VoIPController::InitializeTimers()
if (statsDump && incomingStreams.size() == 1)
{
shared_ptr<JitterBuffer> &jitterBuffer = incomingStreams[0]->jitterBuffer;
//fprintf(statsDump, "Time\tRTT\tLISeq\tLASeq\tCWnd\tBitrate\tJitter\tJDelay\tAJDelay\n");
fprintf(statsDump, "%.3f\t%.3f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%.3f\t%.3f\t%.3f\n",
GetCurrentTime() - connectionInitTime,
endpoints.at(currentEndpoint).rtts[0],
lastRemoteSeq,
(uint32_t)seq,
lastRemoteAckSeq,
recvLossCount,
conctl ? conctl->GetSendLossCount() : 0,
conctl ? (int)conctl->GetInflightDataSize() : 0,
encoder ? encoder->GetBitrate() : 0,
encoder ? encoder->GetPacketLoss() : 0,
jitterBuffer ? jitterBuffer->GetLastMeasuredJitter() : 0,
jitterBuffer ? jitterBuffer->GetLastMeasuredDelay() * 0.06 : 0,
jitterBuffer ? jitterBuffer->GetAverageDelay() * 0.06 : 0);
statsDump << std::setprecision(3)
<< GetCurrentTime() - connectionInitTime
<< endpoints.at(currentEndpoint).rtts[0]
<< lastRemoteSeq
<< (uint32_t)seq
<< lastRemoteAckSeq
<< recvLossCount
<< conctl.GetSendLossCount()
<< (int)conctl.GetInflightDataSize()
<< (encoder ? encoder->GetBitrate() : 0)
<< (encoder ? encoder->GetPacketLoss() : 0)
<< (jitterBuffer ? jitterBuffer->GetLastMeasuredJitter() : 0)
<< (jitterBuffer ? jitterBuffer->GetLastMeasuredDelay() * 0.06 : 0)
<< (jitterBuffer ? jitterBuffer->GetAverageDelay() * 0.06 : 0);
}
},
0.1, 0.1);
@ -1317,7 +1183,7 @@ void VoIPController::HandleAudioInput(unsigned char *data, size_t len, unsigned
/*.endpoint=*/0,
};
conctl->PacketSent(p.seq, p.len);
conctl.PacketSent(p.seq, p.len);
SendOrEnqueuePacket(move(p));
if (peerVersion < 7 && secondaryLen && shittyInternetMode)
@ -1353,9 +1219,9 @@ void VoIPController::HandleAudioInput(unsigned char *data, size_t len, unsigned
});
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
if (audioPreprocDataCallback && preprocDecoder)
if (audioPreprocDataCallback)
{
int size = opus_decode(preprocDecoder, data, len, preprocBuffer, 4096, 0);
int size = opus_decode(preprocDecoder.get(), data, len, preprocBuffer, 4096, 0);
audioPreprocDataCallback(preprocBuffer, size);
}
#endif
@ -1370,7 +1236,7 @@ void VoIPController::InitializeAudio()
audioInput = audioIO->GetInput();
audioOutput = audioIO->GetOutput();
#ifdef __ANDROID__
audio::AudioInputAndroid *androidInput = dynamic_cast<audio::AudioInputAndroid *>(audioInput);
audio::AudioInputAndroid *androidInput = dynamic_cast<audio::AudioInputAndroid *>(audioInput.get());
if (androidInput)
{
unsigned int effects = androidInput->GetEnabledEffects();
@ -1389,20 +1255,20 @@ void VoIPController::InitializeAudio()
SetAudioOutputDuckingEnabled(macAudioDuckingEnabled);
#endif
LOGI("AEC: %d NS: %d AGC: %d", config.enableAEC, config.enableNS, config.enableAGC);
echoCanceller = new EchoCanceller(config.enableAEC, config.enableNS, config.enableAGC);
encoder = new OpusEncoder(audioInput, true);
echoCanceller.reset(new EchoCanceller(config.enableAEC, config.enableNS, config.enableAGC));
encoder.reset(new OpusEncoder(audioInput, true));
encoder->SetCallback(bind(&VoIPController::HandleAudioInput, this, placeholders::_1, placeholders::_2, placeholders::_3, placeholders::_4));
encoder->SetOutputFrameDuration(outgoingAudioStream->frameDuration);
encoder->SetEchoCanceller(echoCanceller);
encoder->SetSecondaryEncoderEnabled(false);
if (config.enableVolumeControl)
{
encoder->AddAudioEffect(&inputVolume);
encoder->AddAudioEffect(inputVolume);
}
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
dynamic_cast<audio::AudioInputCallback *>(audioInput)->SetDataCallback(audioInputDataCallback);
dynamic_cast<audio::AudioOutputCallback *>(audioOutput)->SetDataCallback(audioOutputDataCallback);
dynamic_cast<audio::AudioInputCallback *>(audioInput.get())->SetDataCallback(audioInputDataCallback);
dynamic_cast<audio::AudioOutputCallback *>(audioOutput.get())->SetDataCallback(audioOutputDataCallback);
#endif
if (!audioOutput->IsInitialized())
@ -1444,7 +1310,7 @@ void VoIPController::OnAudioOutputReady()
stm->decoder->SetEchoCanceller(echoCanceller);
if (config.enableVolumeControl)
{
stm->decoder->AddAudioEffect(&outputVolume);
stm->decoder->AddAudioEffect(outputVolume);
}
stm->decoder->SetJitterBuffer(stm->jitterBuffer);
stm->decoder->SetFrameDuration(stm->frameDuration);
@ -1774,7 +1640,6 @@ void VoIPController::InitUDPProxy()
if (realUdpSocket != udpSocket)
{
udpSocket->Close();
delete udpSocket;
udpSocket = realUdpSocket;
}
char sbuf[128];
@ -1787,12 +1652,12 @@ void VoIPController::InitUDPProxy()
return;
}
NetworkSocket *tcp = NetworkSocket::Create(NetworkProtocol::TCP);
std::shared_ptr<NetworkSocket> tcp = NetworkSocket::Create(NetworkProtocol::TCP);
tcp->Connect(resolvedProxyAddress, proxyPort);
vector<NetworkSocket *> writeSockets;
vector<NetworkSocket *> readSockets;
vector<NetworkSocket *> errorSockets;
vector<std::shared_ptr<NetworkSocket>> writeSockets;
vector<std::shared_ptr<NetworkSocket>> readSockets;
vector<std::shared_ptr<NetworkSocket>> errorSockets;
while (!tcp->IsFailed() && !tcp->IsReadyToSend())
{
@ -1800,12 +1665,12 @@ void VoIPController::InitUDPProxy()
if (!NetworkSocket::Select(readSockets, writeSockets, errorSockets, selectCanceller))
{
LOGW("Select canceled while waiting for proxy control socket to connect");
delete tcp;
tcp.reset();
return;
}
}
LOGV("UDP proxy control socket ready to send");
NetworkSocketSOCKS5Proxy *udpProxy = new NetworkSocketSOCKS5Proxy(tcp, realUdpSocket, proxyUsername, proxyPassword);
std::shared_ptr<NetworkSocketSOCKS5Proxy> udpProxy = std::make_shared<NetworkSocketSOCKS5Proxy>(tcp, realUdpSocket, proxyUsername, proxyPassword);
udpProxy->OnReadyToSend();
writeSockets.clear();
while (!udpProxy->IsFailed() && !tcp->IsFailed() && !udpProxy->IsReadyToSend())
@ -1817,7 +1682,7 @@ void VoIPController::InitUDPProxy()
if (!NetworkSocket::Select(readSockets, writeSockets, errorSockets, selectCanceller))
{
LOGW("Select canceled while waiting for UDP proxy to initialize");
delete udpProxy;
udpProxy.reset();
return;
}
if (!readSockets.empty())
@ -1828,7 +1693,7 @@ void VoIPController::InitUDPProxy()
if (udpProxy->IsFailed())
{
udpProxy->Close();
delete udpProxy;
udpProxy.reset();
proxySupportsUDP = false;
}
else
@ -1864,9 +1729,9 @@ void VoIPController::RunRecvThread()
needReInitUdpProxy = false;
}
vector<NetworkSocket *> readSockets;
vector<NetworkSocket *> errorSockets;
vector<NetworkSocket *> writeSockets;
vector<std::shared_ptr<NetworkSocket>> readSockets;
vector<std::shared_ptr<NetworkSocket>> errorSockets;
vector<std::shared_ptr<NetworkSocket>> writeSockets;
readSockets.push_back(udpSocket);
errorSockets.push_back(realUdpSocket);
if (!realUdpSocket->IsReadyToSend())
@ -1881,13 +1746,13 @@ void VoIPController::RunRecvThread()
{
if (e.socket)
{
readSockets.push_back(&*e.socket);
errorSockets.push_back(&*e.socket);
readSockets.push_back(e.socket);
errorSockets.push_back(e.socket);
if (!e.socket->IsReadyToSend())
{
NetworkSocketSOCKS5Proxy *proxy = dynamic_cast<NetworkSocketSOCKS5Proxy *>(&*e.socket);
if (!proxy || proxy->NeedSelectForSending())
writeSockets.push_back(&*e.socket);
writeSockets.push_back(e.socket);
}
}
}
@ -1914,12 +1779,12 @@ void VoIPController::RunRecvThread()
return;
}
MutexGuard m(endpointsMutex);
for (NetworkSocket *&socket : errorSockets)
for (std::shared_ptr<NetworkSocket> &socket : errorSockets)
{
for (pair<const int64_t, Endpoint> &_e : endpoints)
{
Endpoint &e = _e.second;
if (e.socket && &*e.socket == socket)
if (e.socket == socket)
{
e.socket->Close();
e.socket.reset();
@ -1930,7 +1795,7 @@ void VoIPController::RunRecvThread()
continue;
}
for (NetworkSocket *&socket : readSockets)
for (std::shared_ptr<NetworkSocket> &socket : readSockets)
{
//while(packet.length){
NetworkPacket packet = socket->Receive();
@ -2493,7 +2358,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
LOGI("resuming sending");
}
lastRemoteAckSeq = ackId;
conctl->PacketAcknowledged(ackId);
conctl.PacketAcknowledged(ackId);
// Status list of acked seqnos, starting from the seq explicitly present in the packet + up to 32 seqs ago
std::array<uint32_t, 33> peerAcks{0};
@ -2524,7 +2389,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
}
// TODO move this to a PacketSender
conctl->PacketAcknowledged(opkt.seq);
conctl.PacketAcknowledged(opkt.seq);
}
}
@ -2569,7 +2434,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
{
for (auto x = currentExtras.begin(); x != currentExtras.end();)
{
if (x->firstContainingSeq != 0 && (lastRemoteAckSeq == x->firstContainingSeq || seqgt(lastRemoteAckSeq, x->firstContainingSeq)))
if (x->firstContainingSeq != 0 && seqgte(lastRemoteAckSeq, x->firstContainingSeq))
{
LOGV("Peer acknowledged extra type %u length %u", x->type, (unsigned int)x->data.Length());
ProcessAcknowledgedOutgoingExtra(*x);
@ -2582,7 +2447,7 @@ void VoIPController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint &srcE
}
Endpoint *_currentEndpoint = &endpoints.at(currentEndpoint);
if (srcEndpoint.id != currentEndpoint && srcEndpoint.IsReflector() && ((_currentEndpoint->type != Endpoint::Type::UDP_RELAY && _currentEndpoint->type != Endpoint::Type::TCP_RELAY) || _currentEndpoint->averageRTT == 0))
if (srcEndpoint.id != currentEndpoint && srcEndpoint.IsReflector() && (_currentEndpoint->IsP2P() || _currentEndpoint->averageRTT == 0))
{
if (seqgt(lastSentSeq - 32, lastRemoteAckSeq))
{
@ -3348,7 +3213,7 @@ bool VoIPController::SendOrEnqueuePacket(PendingOutgoingPacket pkt, bool enqueue
}
else if (proxyProtocol == PROXY_SOCKS5)
{
NetworkSocket *tcp = NetworkSocket::Create(NetworkProtocol::TCP);
std::shared_ptr<NetworkSocket> tcp = NetworkSocket::Create(NetworkProtocol::TCP);
tcp->Connect(resolvedProxyAddress, proxyPort);
shared_ptr<NetworkSocketSOCKS5Proxy> proxy = make_shared<NetworkSocketSOCKS5Proxy>(tcp, nullptr, proxyUsername, proxyPassword);
endpoint->socket = proxy;
@ -3875,7 +3740,7 @@ void VoIPController::SetVideoSource(video::VideoSource *source)
}
if (!videoPacketSender)
videoPacketSender = new video::VideoPacketSender(this, source, stm);
videoPacketSender.reset(new video::VideoPacketSender(this, source, stm));
else
videoPacketSender->SetSource(source);
}
@ -4067,11 +3932,11 @@ void VoIPController::EvaluateUdpPingResults()
if (avgPongs == 0.0 && proxyProtocol == PROXY_SOCKS5 && udpSocket != realUdpSocket)
{
LOGI("Proxy does not let UDP through, closing proxy connection and using UDP directly");
NetworkSocket *proxySocket = udpSocket;
std::shared_ptr<NetworkSocket> proxySocket = udpSocket;
proxySocket->Close();
udpSocket = realUdpSocket;
selectCanceller->CancelSelect();
delete proxySocket;
proxySocket.reset();
proxySupportsUDP = false;
ResetUdpAvailability();
return;
@ -4225,9 +4090,9 @@ void VoIPController::UpdateRTT()
void VoIPController::UpdateCongestion()
{
if (conctl && encoder)
if (encoder)
{
uint32_t sendLossCount = conctl->GetSendLossCount();
uint32_t sendLossCount = conctl.GetSendLossCount();
sendLossCountHistory.Add(sendLossCount - prevSendLossCount);
prevSendLossCount = sendLossCount;
double packetsPerSec = 1000 / (double)outgoingStreams[0]->frameDuration;
@ -4301,7 +4166,7 @@ void VoIPController::UpdateCongestion()
void VoIPController::UpdateAudioBitrate()
{
if (encoder && conctl)
if (encoder)
{
double time = GetCurrentTime();
if ((audioInput && !audioInput->IsInitialized()) || (audioOutput && !audioOutput->IsInitialized()))
@ -4311,7 +4176,7 @@ void VoIPController::UpdateAudioBitrate()
SetState(STATE_FAILED);
}
int act = conctl->GetBandwidthControlAction();
int act = conctl.GetBandwidthControlAction();
if (shittyInternetMode)
{
encoder->SetBitrate(8000);
@ -4528,10 +4393,7 @@ void VoIPController::TickJitterBufferAndCongestionControl()
stm->jitterBuffer->Tick();
}
}
if (conctl)
{
conctl->Tick();
}
conctl.Tick();
//MutexGuard m(queuedPacketsMutex);
double currentTime = GetCurrentTime();
@ -4552,7 +4414,7 @@ void VoIPController::TickJitterBufferAndCongestionControl()
}
else if (pkt.type == PKT_STREAM_DATA)
{
conctl->PacketLost(pkt.seq);
conctl.PacketLost(pkt.seq);
}
}
}

View File

@ -17,6 +17,8 @@
#include <stdint.h>
#include <vector>
#include <deque>
#include <fstream>
#include <iomanip>
#include <string>
#include <unordered_map>
#include <map>
@ -43,6 +45,12 @@
#include "tools/utils.h"
#include "controller/PrivateDefines.h"
#if defined HAVE_CONFIG_H || defined TGVOIP_USE_INSTALLED_OPUS
#include <opus/opus.h>
#else
#include <opus/opus.h>
#endif
#define LIBTGVOIP_VERSION "2.5"
#ifdef _WIN32
@ -177,10 +185,10 @@ public:
struct TrafficStats
{
uint64_t bytesSentWifi;
uint64_t bytesRecvdWifi;
uint64_t bytesSentMobile;
uint64_t bytesRecvdMobile;
uint64_t bytesSentWifi = 0;
uint64_t bytesRecvdWifi = 0;
uint64_t bytesSentMobile = 0;
uint64_t bytesRecvdMobile = 0;
};
VoIPController();
@ -580,116 +588,129 @@ private:
void NetworkPacketReceived(std::shared_ptr<NetworkPacket> packet);
void TrySendQueuedPackets();
int state;
int state = STATE_WAIT_INIT;
std::map<int64_t, Endpoint> endpoints;
int64_t currentEndpoint = 0;
int64_t preferredRelay = 0;
int64_t peerPreferredRelay = 0;
std::atomic<bool> runReceiver;
std::atomic<uint32_t> seq;
uint32_t lastRemoteSeq; // Seqno of last received packet
uint32_t lastRemoteAckSeq; // Seqno of last sent packet acked by remote
uint32_t lastSentSeq; // Seqno of last sent packet
std::atomic<bool> runReceiver = ATOMIC_VAR_INIT(false);
std::atomic<uint32_t> seq = ATOMIC_VAR_INIT(1);
uint32_t lastRemoteSeq = 0; // Seqno of last received packet
uint32_t lastRemoteAckSeq = 0; // Seqno of last sent packet acked by remote
uint32_t lastSentSeq = 0; // Seqno of last sent packet
std::vector<RecentOutgoingPacket> recentOutgoingPackets;
std::array<uint32_t, MAX_RECENT_PACKETS> recentIncomingSeqs{};
size_t recentIncomingSeqIdx = 0;
HistoricBuffer<uint32_t, 10, double> sendLossCountHistory;
uint32_t audioTimestampIn;
uint32_t audioTimestampOut;
tgvoip::audio::AudioIO *audioIO = NULL;
tgvoip::audio::AudioInput *audioInput = NULL;
tgvoip::audio::AudioOutput *audioOutput = NULL;
OpusEncoder *encoder;
uint32_t audioTimestampIn = 0;
uint32_t audioTimestampOut = 0;
std::unique_ptr<OpusEncoder> encoder;
std::unique_ptr<tgvoip::audio::AudioIO> audioIO;
// Obtained from audioIO
std::shared_ptr<tgvoip::audio::AudioInput> audioInput;
std::shared_ptr<tgvoip::audio::AudioOutput> audioOutput;
// Shared between encoder and decoder
std::shared_ptr<EchoCanceller> echoCanceller;
std::unique_ptr<Thread> recvThread;
std::unique_ptr<Thread> sendThread;
std::vector<PendingOutgoingPacket> sendQueue;
EchoCanceller *echoCanceller;
std::atomic<bool> stopping;
bool audioOutStarted;
Thread *recvThread;
Thread *sendThread;
uint32_t packetsReceived;
uint32_t recvLossCount;
uint32_t prevSendLossCount;
std::atomic<bool> stopping = ATOMIC_VAR_INIT(false);
bool audioOutStarted = false;
uint32_t packetsReceived = 0;
uint32_t recvLossCount = 0;
uint32_t prevSendLossCount = 0;
uint32_t firstSentPing;
HistoricBuffer<double, 32> rttHistory;
bool waitingForAcks;
int networkType;
int dontSendPackets;
bool waitingForAcks = false;
int networkType = NET_TYPE_UNKNOWN;
int dontSendPackets = 0;
int lastError;
bool micMuted;
bool micMuted = false;
uint32_t maxBitrate;
//
std::vector<std::shared_ptr<Stream>> outgoingStreams;
std::vector<std::shared_ptr<Stream>> incomingStreams;
unsigned char encryptionKey[256];
unsigned char keyFingerprint[8];
unsigned char callID[16];
double stateChangeTime;
bool waitingForRelayPeerInfo;
bool allowP2p;
bool dataSavingMode;
bool dataSavingRequestedByPeer;
bool waitingForRelayPeerInfo = false;
bool allowP2p = true;
bool dataSavingMode = false;
bool dataSavingRequestedByPeer = false;
std::string activeNetItfName;
double publicEndpointsReqTime;
double publicEndpointsReqTime = 0;
std::vector<QueuedPacket> queuedPackets;
double connectionInitTime;
double lastRecvPacketTime;
double connectionInitTime = 0;
double lastRecvPacketTime = 0;
Config config;
int32_t peerVersion;
CongestionControl *conctl;
int32_t peerVersion = 0;
CongestionControl conctl;
TrafficStats stats;
bool receivedInit;
bool receivedInitAck;
bool receivedInit = false;
bool receivedInitAck = false;
bool isOutgoing;
NetworkSocket *udpSocket;
NetworkSocket *realUdpSocket;
FILE *statsDump;
// Might point to the same or different objects
std::shared_ptr<NetworkSocket> udpSocket;
std::shared_ptr<NetworkSocket> realUdpSocket;
std::ofstream statsDump;
std::string currentAudioInput;
std::string currentAudioOutput;
bool useTCP;
bool useUDP;
bool didAddTcpRelays;
SocketSelectCanceller *selectCanceller;
bool useTCP = false;
bool useUDP = true;
bool didAddTcpRelays = false;
std::unique_ptr<SocketSelectCanceller> selectCanceller;
HistoricBuffer<unsigned char, 4, int> signalBarsHistory;
bool audioStarted = false;
int udpConnectivityState;
double lastUdpPingTime;
int udpPingCount;
int echoCancellationStrength;
int udpConnectivityState = UDP_UNKNOWN;
double lastUdpPingTime = 0;
int udpPingCount = 0;
int echoCancellationStrength = 1;
int proxyProtocol;
int proxyProtocol = PROXY_NONE;
std::string proxyAddress;
uint16_t proxyPort;
uint16_t proxyPort = 0;
std::string proxyUsername;
std::string proxyPassword;
NetworkAddress resolvedProxyAddress = NetworkAddress::Empty();
uint32_t peerCapabilities;
Callbacks callbacks;
bool didReceiveGroupCallKey;
bool didReceiveGroupCallKeyAck;
bool didSendGroupCallKey;
bool didSendUpgradeRequest;
bool didInvokeUpgradeCallback;
uint32_t peerCapabilities = 0;
Callbacks callbacks{0};
bool didReceiveGroupCallKey = false;
bool didReceiveGroupCallKeyAck = false;
bool didSendGroupCallKey = false;
bool didSendUpgradeRequest = false;
bool didInvokeUpgradeCallback = false;
int32_t connectionMaxLayer;
bool useMTProto2;
bool setCurrentEndpointToTCP;
int32_t connectionMaxLayer = 0;
bool useMTProto2 = false;
bool setCurrentEndpointToTCP = false;
std::vector<UnacknowledgedExtraData> currentExtras;
std::unordered_map<uint8_t, uint64_t> lastReceivedExtrasByType;
bool useIPv6;
bool peerIPv6Available;
bool useIPv6 = false;
bool peerIPv6Available = false;
NetworkAddress myIPv6 = NetworkAddress::Empty();
bool shittyInternetMode;
bool shittyInternetMode = false;
uint8_t extraEcLevel = 0;
std::deque<Buffer> ecAudioPackets;
bool didAddIPv6Relays;
bool didSendIPv6Endpoint;
bool didAddIPv6Relays = false;
bool didSendIPv6Endpoint = false;
int publicEndpointsReqCount = 0;
bool wasEstablished = false;
bool receivedFirstStreamPacket = false;
std::atomic<unsigned int> unsentStreamPackets;
std::atomic<unsigned int> unsentStreamPackets = ATOMIC_VAR_INIT(0);
HistoricBuffer<unsigned int, 5> unsentStreamPacketsHistory;
bool needReInitUdpProxy = true;
bool needRate = false;
@ -700,8 +721,9 @@ private:
uint32_t initTimeoutID = MessageThread::INVALID_ID;
uint32_t udpPingTimeoutID = MessageThread::INVALID_ID;
effects::Volume outputVolume;
effects::Volume inputVolume;
// Using a shared_ptr is redundant here, but it allows more flexibility in the OpusEncoder API
std::shared_ptr<effects::Volume> outputVolume = std::make_shared<effects::Volume>();
std::shared_ptr<effects::Volume> inputVolume = std::make_shared<effects::Volume>();
std::vector<uint32_t> peerVideoDecoders;
@ -717,17 +739,17 @@ private:
std::function<void(int16_t *, size_t)> audioInputDataCallback;
std::function<void(int16_t *, size_t)> audioOutputDataCallback;
std::function<void(int16_t *, size_t)> audioPreprocDataCallback;
::OpusDecoder *preprocDecoder = nullptr;
std::unique_ptr<::OpusDecoder, decltype(&opus_decoder_destroy)> preprocDecoder{opus_decoder_create(48000, 1, NULL), &opus_decoder_destroy};
int16_t preprocBuffer[4096];
#endif
#if defined(__APPLE__) && defined(TARGET_OS_OSX)
bool macAudioDuckingEnabled = true;
#endif
video::VideoRenderer *videoRenderer = NULL;
video::VideoRenderer *videoRenderer = nullptr;
uint32_t lastReceivedVideoFrameNumber = UINT32_MAX;
video::VideoPacketSender *videoPacketSender = NULL;
std::unique_ptr<video::VideoPacketSender> videoPacketSender;
uint32_t sendLosses = 0;
uint32_t unacknowledgedIncomingPacketCount = 0;
@ -770,7 +792,7 @@ private:
public:
#ifdef __APPLE__
static double machTimebase;
static uint64_t machTimestart;
static uint64_t machTimestart = 0;
#endif
#ifdef _WIN32
static int64_t win32TimeScale;

View File

@ -17,8 +17,6 @@ using namespace std;
VoIPGroupController::VoIPGroupController(int32_t timeDifference)
{
audioMixer = new AudioMixer();
memset(&callbacks, 0, sizeof(callbacks));
userSelfID = 0;
this->timeDifference = timeDifference;
LOGV("Created VoIPGroupController; timeDifference=%d", timeDifference);
@ -31,14 +29,7 @@ VoIPGroupController::~VoIPGroupController()
audioOutput->Stop();
}
LOGD("before stop audio mixer");
audioMixer->Stop();
delete audioMixer;
for (vector<GroupCallParticipant>::iterator p = participants.begin(); p != participants.end(); p++)
{
if (p->levelMeter)
delete p->levelMeter;
}
audioMixer.Stop();
}
void VoIPGroupController::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)
@ -93,7 +84,6 @@ void VoIPGroupController::AddGroupCallParticipant(int32_t userID, unsigned char
GroupCallParticipant p;
p.userID = userID;
memcpy(p.memberTagHash, memberTagHash, sizeof(p.memberTagHash));
p.levelMeter = new AudioLevelMeter();
BufferInputStream ss(serializedStreams, streamsLength);
vector<shared_ptr<Stream>> streams = DeserializeStreams(ss);
@ -120,7 +110,7 @@ void VoIPGroupController::AddGroupCallParticipant(int32_t userID, unsigned char
s->decoder->SetFrameDuration(s->frameDuration);
s->decoder->SetDTX(true);
s->decoder->SetLevelMeter(p.levelMeter);
audioMixer->AddInput(s->callbackWrapper);
audioMixer.AddInput(s->callbackWrapper);
}
incomingStreams.push_back(s);
}
@ -144,11 +134,8 @@ void VoIPGroupController::RemoveGroupCallParticipant(int32_t userID)
if ((*stm)->userID == userID)
{
LOGI("Removed stream %d belonging to user %d", (*stm)->id, userID);
audioMixer->RemoveInput((*stm)->callbackWrapper);
audioMixer.RemoveInput((*stm)->callbackWrapper);
(*stm)->decoder->Stop();
//delete (*stm)->decoder;
//delete (*stm)->jitterBuffer;
//delete (*stm)->callbackWrapper;
stm = incomingStreams.erase(stm);
continue;
}
@ -158,8 +145,6 @@ void VoIPGroupController::RemoveGroupCallParticipant(int32_t userID)
{
if (p->userID == userID)
{
if (p->levelMeter)
delete p->levelMeter;
participants.erase(p);
LOGI("Removed group call participant %d", userID);
break;
@ -309,7 +294,7 @@ void VoIPGroupController::ProcessIncomingPacket(NetworkPacket &packet, Endpoint
if(pkt->id==id){
if(!pkt->ackTime){
pkt->ackTime=GetCurrentTime();
conctl->PacketAcknowledged(pkt->seq);
conctl.PacketAcknowledged(pkt->seq);
//LOGV("relay acknowledged packet %u", pkt->seq);
if(seqgt(pkt->seq, lastRemoteAckSeq))
lastRemoteAckSeq=pkt->seq;
@ -583,12 +568,12 @@ void VoIPGroupController::SendRelayPings()
void VoIPGroupController::OnAudioOutputReady()
{
encoder->SetDTX(true);
audioMixer->SetOutput(audioOutput);
audioMixer->SetEchoCanceller(echoCanceller);
audioMixer->Start();
audioMixer.SetOutput(audioOutput.get());
audioMixer.SetEchoCanceller(echoCanceller.get());
audioMixer.Start();
audioOutput->Start();
audioOutStarted = true;
encoder->SetLevelMeter(&selfLevelMeter);
encoder->SetLevelMeter(selfLevelMeter);
}
void VoIPGroupController::WritePacketHeader(uint32_t seq, BufferOutputStream *s, unsigned char type, uint32_t length, PacketSender *source)
@ -609,7 +594,7 @@ void VoIPGroupController::WritePacketHeader(uint32_t seq, BufferOutputStream *s,
if (type == PKT_STREAM_DATA || type == PKT_STREAM_DATA_X2 || type == PKT_STREAM_DATA_X3)
{
conctl->PacketSent(seq, length);
conctl.PacketSent(seq, length);
}
/*if(pflags & PFLAG_HAS_CALL_ID){
@ -722,7 +707,7 @@ int32_t VoIPGroupController::GetCurrentUnixtime()
float VoIPGroupController::GetParticipantAudioLevel(int32_t userID)
{
if (userID == userSelfID)
return selfLevelMeter.GetLevel();
return selfLevelMeter->GetLevel();
MutexGuard m(participantsMutex);
for (vector<GroupCallParticipant>::iterator p = participants.begin(); p != participants.end(); ++p)
{
@ -777,7 +762,7 @@ void VoIPGroupController::SetParticipantVolume(int32_t userID, float volume)
else
db = 0.0f;
//LOGV("Setting user %u audio volume to %.2f dB", userID, db);
audioMixer->SetInputVolume((*s)->callbackWrapper, db);
audioMixer.SetInputVolume((*s)->callbackWrapper, db);
}
break;
}
@ -850,11 +835,11 @@ std::string VoIPGroupController::GetDebugString()
"Send/recv losses: %u/%u (%d%%)\n"
"Audio bitrate: %d kbit\n"
"Bytes sent/recvd: %llu/%llu\n\n",
(int)(conctl->GetAverageRTT() * 1000), (int)(conctl->GetMinimumRTT() * 1000),
int(conctl->GetInflightDataSize()), int(conctl->GetCongestionWindow()),
(int)(conctl.GetAverageRTT() * 1000), (int)(conctl.GetMinimumRTT() * 1000),
int(conctl.GetInflightDataSize()), int(conctl.GetCongestionWindow()),
keyFingerprint[0], keyFingerprint[1], keyFingerprint[2], keyFingerprint[3], keyFingerprint[4], keyFingerprint[5], keyFingerprint[6], keyFingerprint[7],
lastSentSeq, lastRemoteAckSeq,
conctl->GetSendLossCount(), recvLossCount, encoder ? encoder->GetPacketLoss() : 0,
conctl.GetSendLossCount(), recvLossCount, encoder ? encoder->GetPacketLoss() : 0,
encoder ? (encoder->GetBitrate() / 1000) : 0,
(long long unsigned int)(stats.bytesSentMobile + stats.bytesSentWifi),
(long long unsigned int)(stats.bytesRecvdMobile + stats.bytesRecvdWifi));

View File

@ -49,7 +49,7 @@ private:
int32_t userID;
unsigned char memberTagHash[32];
std::vector<std::shared_ptr<Stream>> streams;
AudioLevelMeter *levelMeter;
std::shared_ptr<AudioLevelMeter> levelMeter = std::make_shared<AudioLevelMeter>();
};
std::vector<GroupCallParticipant> participants;
unsigned char reflectorSelfTag[16];
@ -57,9 +57,9 @@ private:
unsigned char reflectorSelfTagHash[32];
int32_t userSelfID;
Endpoint groupReflector;
AudioMixer *audioMixer;
AudioLevelMeter selfLevelMeter;
Callbacks groupCallbacks;
AudioMixer audioMixer;
std::shared_ptr<AudioLevelMeter> selfLevelMeter = std::make_shared<AudioLevelMeter>();
Callbacks groupCallbacks {};
struct PacketIdMapping
{
uint32_t seq;

View File

@ -46,7 +46,7 @@ using namespace tgvoip;
using namespace tgvoip::audio;
using namespace std;
AudioIO *AudioIO::Create(std::string inputDevice, std::string outputDevice)
std::unique_ptr<AudioIO> AudioIO::Create(std::string inputDevice, std::string outputDevice)
{
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
return new AudioIOCallback();

View File

@ -23,9 +23,9 @@ public:
AudioIO(){};
virtual ~AudioIO(){};
TGVOIP_DISALLOW_COPY_AND_ASSIGN(AudioIO);
static AudioIO *Create(std::string inputDevice, std::string outputDevice);
virtual AudioInput *GetInput() = 0;
virtual AudioOutput *GetOutput() = 0;
static std::unique_ptr<AudioIO> Create(std::string inputDevice, std::string outputDevice);
virtual std::shared_ptr<AudioInput> GetInput() = 0;
virtual std::shared_ptr<AudioOutput> GetOutput() = 0;
bool Failed();
std::string GetErrorDescription();
@ -40,35 +40,29 @@ class ContextlessAudioIO : public AudioIO
public:
ContextlessAudioIO()
{
input = new I();
output = new O();
input = std::make_shared<I>();
output = std::make_shared<O>();
}
ContextlessAudioIO(std::string inputDeviceID, std::string outputDeviceID)
{
input = new I(inputDeviceID);
output = new O(outputDeviceID);
input = std::make_shared<I>(inputDeviceID);
output = std::make_shared<O>(outputDeviceID);
}
virtual ~ContextlessAudioIO()
{
delete input;
delete output;
}
virtual AudioInput *GetInput()
virtual std::shared_ptr<AudioInput> GetInput()
{
return input;
}
virtual AudioOutput *GetOutput()
virtual std::shared_ptr<AudioOutput> *GetOutput()
{
return output;
}
private:
I *input;
O *output;
std::shared_ptr<I> input;
std::shared_ptr<O> output;
};
} // namespace audio
} // namespace tgvoip

View File

@ -15,22 +15,20 @@ using namespace tgvoip::audio;
AudioIOCallback::AudioIOCallback()
{
input = new AudioInputCallback();
output = new AudioOutputCallback();
input = std::make_shared<AudioInputCallback>();
output = std::make_shared<AudioOutputCallback>();
}
AudioIOCallback::~AudioIOCallback()
{
delete input;
delete output;
}
AudioInput *AudioIOCallback::GetInput()
std::shared_ptr<AudioInput> AudioIOCallback::GetInput()
{
return input;
}
AudioOutput *AudioIOCallback::GetOutput()
std::shared_ptr<AudioInput> AudioIOCallback::GetOutput()
{
return output;
}

View File

@ -7,9 +7,10 @@
#ifndef LIBTGVOIP_AUDIO_IO_CALLBACK
#define LIBTGVOIP_AUDIO_IO_CALLBACK
#include "AudioIO.h"
#include <functional>
#include <memory>
#include "AudioIO.h"
#include "../tools/threading.h"
namespace tgvoip
@ -56,12 +57,12 @@ class AudioIOCallback : public AudioIO
public:
AudioIOCallback();
virtual ~AudioIOCallback();
virtual AudioInput *GetInput() override;
virtual AudioOutput *GetOutput() override;
virtual std::shared_ptr<AudioInput> GetInput() override;
virtual std::shared_ptr<AudioOutput> GetOutput() override;
private:
AudioInputCallback *input;
AudioOutputCallback *output;
std::shared_ptr<AudioInputCallback> input;
std::shared_ptr<AudioOutputCallback> output;
};
} // namespace audio
} // namespace tgvoip

View File

@ -123,6 +123,11 @@ inline bool seqgt(uint32_t s1, uint32_t s2)
return ((s1 > s2) && (s1 - s2 <= SEQ_MAX / 2)) || ((s1 < s2) && (s2 - s1 > SEQ_MAX / 2));
}
inline bool seqgte(uint32_t s1, uint32_t s2)
{
return s1 == s2 || seqgt(s1, s2);
}
#define NEED_RATE_FLAG_SHITTY_INTERNET_MODE 1
#define NEED_RATE_FLAG_UDP_NA 2
#define NEED_RATE_FLAG_UDP_BAD 4

View File

@ -10,11 +10,6 @@
#include <assert.h>
#include <math.h>
#include <algorithm>
#if defined HAVE_CONFIG_H || defined TGVOIP_USE_INSTALLED_OPUS
#include <opus/opus.h>
#else
#include <opus/opus.h>
#endif
#include "VoIPController.h"
@ -34,12 +29,6 @@ tgvoip::OpusDecoder::OpusDecoder(const std::unique_ptr<MediaStreamItf> &dst, boo
Initialize(isAsync, needEC);
}
tgvoip::OpusDecoder::OpusDecoder(MediaStreamItf *dst, bool isAsync, bool needEC)
{
dst->SetCallback(OpusDecoder::Callback, this);
Initialize(isAsync, needEC);
}
void tgvoip::OpusDecoder::Initialize(bool isAsync, bool needEC)
{
async = isAsync;
@ -87,7 +76,7 @@ tgvoip::OpusDecoder::~OpusDecoder()
delete semaphore;
}
void tgvoip::OpusDecoder::SetEchoCanceller(EchoCanceller *canceller)
void tgvoip::OpusDecoder::SetEchoCanceller(const std::shared_ptr<EchoCanceller> &canceller)
{
echoCanceller = canceller;
}
@ -212,7 +201,7 @@ void tgvoip::OpusDecoder::RunThread()
Buffer buf = bufferPool.Get();
if (remainingDataLen > 0)
{
for (effects::AudioEffect *&effect : postProcEffects)
for (auto &effect : postProcEffects)
{
effect->Process(reinterpret_cast<int16_t *>(processedBuffer + (PACKET_SIZE * i)), 960);
}
@ -312,7 +301,7 @@ void tgvoip::OpusDecoder::SetFrameDuration(uint32_t duration)
packetsPerFrame = frameDuration / 20;
}
void tgvoip::OpusDecoder::SetJitterBuffer(std::shared_ptr<JitterBuffer> jitterBuffer)
void tgvoip::OpusDecoder::SetJitterBuffer(const std::shared_ptr<JitterBuffer> &jitterBuffer)
{
this->jitterBuffer = jitterBuffer;
}
@ -322,19 +311,19 @@ void tgvoip::OpusDecoder::SetDTX(bool enable)
enableDTX = enable;
}
void tgvoip::OpusDecoder::SetLevelMeter(AudioLevelMeter *levelMeter)
void tgvoip::OpusDecoder::SetLevelMeter(const std::shared_ptr<AudioLevelMeter> &levelMeter)
{
this->levelMeter = levelMeter;
}
void tgvoip::OpusDecoder::AddAudioEffect(effects::AudioEffect *effect)
void tgvoip::OpusDecoder::AddAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect)
{
postProcEffects.push_back(effect);
}
void tgvoip::OpusDecoder::RemoveAudioEffect(effects::AudioEffect *effect)
void tgvoip::OpusDecoder::RemoveAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect)
{
std::vector<effects::AudioEffect *>::iterator i = std::find(postProcEffects.begin(), postProcEffects.end(), effect);
auto i = std::find(postProcEffects.begin(), postProcEffects.end(), effect);
if (i != postProcEffects.end())
postProcEffects.erase(i);
}

View File

@ -19,6 +19,7 @@
#include <memory>
#include <atomic>
struct OpusDecoder;
namespace tgvoip
@ -33,16 +34,15 @@ public:
OpusDecoder(const std::shared_ptr<MediaStreamItf> &dst, bool isAsync, bool needEC);
OpusDecoder(const std::unique_ptr<MediaStreamItf> &dst, bool isAsync, bool needEC);
OpusDecoder(MediaStreamItf *dst, bool isAsync, bool needEC);
virtual ~OpusDecoder();
size_t HandleCallback(unsigned char *data, size_t len);
void SetEchoCanceller(EchoCanceller *canceller);
void SetEchoCanceller(const std::shared_ptr<EchoCanceller> &canceller);
void SetFrameDuration(uint32_t duration);
void SetJitterBuffer(std::shared_ptr<JitterBuffer> jitterBuffer);
void SetJitterBuffer(const std::shared_ptr<JitterBuffer> &jitterBuffer);
void SetDTX(bool enable);
void SetLevelMeter(AudioLevelMeter *levelMeter);
void AddAudioEffect(effects::AudioEffect *effect);
void RemoveAudioEffect(effects::AudioEffect *effect);
void SetLevelMeter(const std::shared_ptr<AudioLevelMeter> &levelMeter);
void AddAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect);
void RemoveAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect);
private:
void Initialize(bool isAsync, bool needEC);
@ -61,13 +61,13 @@ private:
Thread *thread;
Semaphore *semaphore;
uint32_t frameDuration;
EchoCanceller *echoCanceller;
std::shared_ptr<EchoCanceller> echoCanceller;
std::shared_ptr<JitterBuffer> jitterBuffer;
AudioLevelMeter *levelMeter;
std::shared_ptr<AudioLevelMeter> levelMeter;
int consecutiveLostPackets;
bool enableDTX;
size_t silentPacketCount;
std::vector<effects::AudioEffect *> postProcEffects;
std::vector<std::shared_ptr<effects::AudioEffect>> postProcEffects;
bool async;
unsigned char nextBuffer[8192];
unsigned char decodeBuffer[8192];

View File

@ -17,7 +17,7 @@
namespace
{
int serverConfigValueToBandwidth(int config)
inline int serverConfigValueToBandwidth(int config)
{
switch (config)
{
@ -36,7 +36,7 @@ int serverConfigValueToBandwidth(int config)
}
} // namespace
tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary) : queue(10)
tgvoip::OpusEncoder::OpusEncoder(const std::shared_ptr<MediaStreamItf> &source, bool needSecondary) : queue(10)
{
this->source = source;
source->SetCallback(tgvoip::OpusEncoder::Callback, this);
@ -74,6 +74,7 @@ tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary) : q
tgvoip::OpusEncoder::~OpusEncoder()
{
Stop();
opus_encoder_destroy(enc);
if (secondaryEncoder)
opus_encoder_destroy(secondaryEncoder);
@ -172,7 +173,7 @@ uint32_t tgvoip::OpusEncoder::GetBitrate()
return requestedBitrate;
}
void tgvoip::OpusEncoder::SetEchoCanceller(EchoCanceller *aec)
void tgvoip::OpusEncoder::SetEchoCanceller(const std::shared_ptr<EchoCanceller> &aec)
{
echoCanceller = aec;
}
@ -200,7 +201,7 @@ void tgvoip::OpusEncoder::RunThread()
echoCanceller->ProcessInput(packet, 960, hasVoice);
if (!postProcEffects.empty())
{
for (effects::AudioEffect *effect : postProcEffects)
for (auto &effect : postProcEffects)
{
effect->Process(packet, 960);
}
@ -282,7 +283,7 @@ void tgvoip::OpusEncoder::SetDTX(bool enable)
opus_encoder_ctl(enc, OPUS_SET_DTX(enable ? 1 : 0));
}
void tgvoip::OpusEncoder::SetLevelMeter(tgvoip::AudioLevelMeter *levelMeter)
void tgvoip::OpusEncoder::SetLevelMeter(const std::shared_ptr<tgvoip::AudioLevelMeter> &levelMeter)
{
this->levelMeter = levelMeter;
}
@ -306,14 +307,14 @@ void tgvoip::OpusEncoder::SetVadMode(bool vad)
{
vadMode = vad;
}
void tgvoip::OpusEncoder::AddAudioEffect(effects::AudioEffect *effect)
void tgvoip::OpusEncoder::AddAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect)
{
postProcEffects.push_back(effect);
}
void tgvoip::OpusEncoder::RemoveAudioEffect(effects::AudioEffect *effect)
void tgvoip::OpusEncoder::RemoveAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect)
{
std::vector<effects::AudioEffect *>::iterator i = std::find(postProcEffects.begin(), postProcEffects.end(), effect);
auto i = std::find(postProcEffects.begin(), postProcEffects.end(), effect);
if (i != postProcEffects.end())
postProcEffects.erase(i);
}

View File

@ -25,23 +25,23 @@ class OpusEncoder
{
public:
TGVOIP_DISALLOW_COPY_AND_ASSIGN(OpusEncoder);
OpusEncoder(MediaStreamItf *source, bool needSecondary);
OpusEncoder(const std::shared_ptr<MediaStreamItf> &source, bool needSecondary);
virtual ~OpusEncoder();
virtual void Start();
virtual void Stop();
void SetBitrate(uint32_t bitrate);
void SetEchoCanceller(EchoCanceller *aec);
void SetEchoCanceller(const std::shared_ptr<EchoCanceller> &aec);
void SetOutputFrameDuration(uint32_t duration);
void SetPacketLoss(int percent);
int GetPacketLoss();
uint32_t GetBitrate();
void SetDTX(bool enable);
void SetLevelMeter(AudioLevelMeter *levelMeter);
void SetLevelMeter(const std::shared_ptr<AudioLevelMeter> &levelMeter);
void SetCallback(std::function<void(unsigned char *, size_t, unsigned char *, size_t)> callback);
void SetSecondaryEncoderEnabled(bool enabled);
void SetVadMode(bool vad);
void AddAudioEffect(effects::AudioEffect *effect);
void RemoveAudioEffect(effects::AudioEffect *effect);
void AddAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect);
void RemoveAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect);
int GetComplexity()
{
return complexity;
@ -52,7 +52,7 @@ private:
void RunThread();
void Encode(int16_t *data, size_t len);
void InvokeCallback(unsigned char *data, size_t length, unsigned char *secondaryData, size_t secondaryLength);
MediaStreamItf *source;
std::shared_ptr<MediaStreamItf> source;
::OpusEncoder *enc;
::OpusEncoder *secondaryEncoder;
unsigned char buffer[4096];
@ -61,16 +61,16 @@ private:
Thread *thread;
BlockingQueue<Buffer> queue;
BufferPool<960 * 2, 10> bufferPool;
EchoCanceller *echoCanceller;
std::shared_ptr<EchoCanceller> echoCanceller;
std::atomic<int> complexity;
std::atomic<bool> running;
uint32_t frameDuration;
int packetLossPercent;
AudioLevelMeter *levelMeter;
std::shared_ptr<AudioLevelMeter> levelMeter;
bool secondaryEncoderEnabled;
bool vadMode = false;
uint32_t vadNoVoiceBitrate;
std::vector<effects::AudioEffect *> postProcEffects;
std::vector<std::shared_ptr<effects::AudioEffect>> postProcEffects;
int secondaryEnabledBandwidth;
int vadModeVoiceBandwidth;
int vadModeNoVoiceBandwidth;

View File

@ -17,23 +17,23 @@ JitterBuffer::JitterBuffer(uint32_t _step) : step(_step),
{
if (step < 30)
{
minMinDelay = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_20", 6);
maxMinDelay = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_20", 25);
maxUsedSlots = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_max_slots_20", 50);
minMinDelay = ServerConfig::GetSharedInstance()->GetUInt("jitter_min_delay_20", 6);
maxMinDelay = ServerConfig::GetSharedInstance()->GetUInt("jitter_max_delay_20", 25);
maxUsedSlots = ServerConfig::GetSharedInstance()->GetUInt("jitter_max_slots_20", 50);
}
else if (step < 50)
{
minMinDelay = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_40", 4);
maxMinDelay = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_40", 15);
maxUsedSlots = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_max_slots_40", 30);
minMinDelay = ServerConfig::GetSharedInstance()->GetUInt("jitter_min_delay_40", 4);
maxMinDelay = ServerConfig::GetSharedInstance()->GetUInt("jitter_max_delay_40", 15);
maxUsedSlots = ServerConfig::GetSharedInstance()->GetUInt("jitter_max_slots_40", 30);
}
else
{
minMinDelay = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_60", 2);
maxMinDelay = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_60", 10);
maxUsedSlots = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_max_slots_60", 20);
minMinDelay = ServerConfig::GetSharedInstance()->GetUInt("jitter_min_delay_60", 2);
maxMinDelay = ServerConfig::GetSharedInstance()->GetUInt("jitter_max_delay_60", 10);
maxUsedSlots = ServerConfig::GetSharedInstance()->GetUInt("jitter_max_slots_60", 20);
}
lossesToReset = (uint32_t)ServerConfig::GetSharedInstance()->GetInt("jitter_losses_to_reset", 20);
lossesToReset = ServerConfig::GetSharedInstance()->GetUInt("jitter_losses_to_reset", 20);
resyncThreshold = ServerConfig::GetSharedInstance()->GetDouble("jitter_resync_threshold", 1.0);
#ifdef TGVOIP_DUMP_JITTER_STATS
#ifdef TGVOIP_JITTER_DUMP_FILE

View File

@ -55,12 +55,12 @@ bool NetworkSocket::IsFailed()
return failed;
}
NetworkSocket *NetworkSocket::Create(NetworkProtocol protocol)
std::shared_ptr<NetworkSocket> NetworkSocket::Create(NetworkProtocol protocol)
{
#ifndef _WIN32
return new NetworkSocketPosix(protocol);
return std::make_shared<NetworkSocketPosix>(protocol);
#else
return new NetworkSocketWinsock(protocol);
return std::make_shared<NetworkSocketWinsock>(protocol);
#endif
}
@ -225,7 +225,7 @@ NetworkAddress NetworkAddress::IPv6(const uint8_t addr[16])
return a;
}
bool NetworkSocket::Select(std::vector<NetworkSocket *> &readFds, std::vector<NetworkSocket *> &writeFds, std::vector<NetworkSocket *> &errorFds, SocketSelectCanceller *canceller)
bool NetworkSocket::Select(std::vector<std::shared_ptr<NetworkSocket>> &readFds, std::vector<std::shared_ptr<NetworkSocket>> &writeFds, std::vector<std::shared_ptr<NetworkSocket>> &errorFds, const std::unique_ptr<SocketSelectCanceller> &canceller)
{
#ifndef _WIN32
return NetworkSocketPosix::Select(readFds, writeFds, errorFds, canceller);
@ -238,27 +238,25 @@ SocketSelectCanceller::~SocketSelectCanceller()
{
}
SocketSelectCanceller *SocketSelectCanceller::Create()
std::unique_ptr<SocketSelectCanceller> SocketSelectCanceller::Create()
{
#ifndef _WIN32
return new SocketSelectCancellerPosix();
return std::move(std::unique_ptr<SocketSelectCanceller>{new SocketSelectCancellerPosix()});
#else
return new SocketSelectCancellerWin32();
return std::move(std::unique_ptr<SocketSelectCanceller>{new SocketSelectCancellerWin32()});
#endif
}
NetworkSocketTCPObfuscated::NetworkSocketTCPObfuscated(NetworkSocket *wrapped) : NetworkSocketWrapper(NetworkProtocol::TCP)
NetworkSocketTCPObfuscated::NetworkSocketTCPObfuscated(const std::shared_ptr<NetworkSocket> &wrapped) : NetworkSocketWrapper(NetworkProtocol::TCP)
{
this->wrapped = wrapped;
}
NetworkSocketTCPObfuscated::~NetworkSocketTCPObfuscated()
{
if (wrapped)
delete wrapped;
}
NetworkSocket *NetworkSocketTCPObfuscated::GetWrapped()
std::shared_ptr<NetworkSocket> NetworkSocketTCPObfuscated::GetWrapped()
{
return wrapped;
}
@ -385,7 +383,7 @@ bool NetworkSocketTCPObfuscated::IsFailed()
return wrapped->IsFailed();
}
NetworkSocketSOCKS5Proxy::NetworkSocketSOCKS5Proxy(NetworkSocket *tcp, NetworkSocket *udp, std::string username, std::string password) : NetworkSocketWrapper(udp ? NetworkProtocol::UDP : NetworkProtocol::TCP)
NetworkSocketSOCKS5Proxy::NetworkSocketSOCKS5Proxy(const std::shared_ptr<NetworkSocket> &tcp, const std::shared_ptr<NetworkSocket> &udp, std::string username, std::string password) : NetworkSocketWrapper(udp ? NetworkProtocol::UDP : NetworkProtocol::TCP)
{
this->tcp = tcp;
this->udp = udp;
@ -395,7 +393,6 @@ NetworkSocketSOCKS5Proxy::NetworkSocketSOCKS5Proxy(NetworkSocket *tcp, NetworkSo
NetworkSocketSOCKS5Proxy::~NetworkSocketSOCKS5Proxy()
{
delete tcp;
}
void NetworkSocketSOCKS5Proxy::Send(NetworkPacket packet)
@ -450,7 +447,7 @@ NetworkPacket NetworkSocketSOCKS5Proxy::Receive(size_t maxLen)
NetworkAddress address = NetworkAddress::Empty();
if (atyp == 1)
{ // IPv4
address = NetworkAddress::IPv4((uint32_t)in.ReadInt32());
address = NetworkAddress::IPv4(in.ReadUInt32());
}
else if (atyp == 4)
{ // IPv6
@ -483,7 +480,7 @@ void NetworkSocketSOCKS5Proxy::Connect(const NetworkAddress address, uint16_t po
connectedPort = port;
}
NetworkSocket *NetworkSocketSOCKS5Proxy::GetWrapped()
std::shared_ptr<NetworkSocket> NetworkSocketSOCKS5Proxy::GetWrapped()
{
return protocol == NetworkProtocol::TCP ? tcp : udp;
}
@ -642,7 +639,7 @@ bool NetworkSocketSOCKS5Proxy::OnReadyToReceive()
}
LOGV("socks5: connect succeeded");
state = ConnectionState::Connected;
tcp = new NetworkSocketTCPObfuscated(tcp);
tcp = std::make_shared<NetworkSocketTCPObfuscated>(tcp);
readyToSend = true;
return tcp->OnReadyToSend();
}
@ -675,7 +672,7 @@ bool NetworkSocketSOCKS5Proxy::OnReadyToReceive()
unsigned char atyp = in.ReadByte();
if (atyp == 1)
{
uint32_t addr = (uint32_t)in.ReadInt32();
uint32_t addr = in.ReadUInt32();
connectedAddress = NetworkAddress::IPv4(addr);
}
else if (atyp == 3)

View File

@ -94,7 +94,7 @@ class SocketSelectCanceller
public:
virtual ~SocketSelectCanceller();
virtual void CancelSelect() = 0;
static SocketSelectCanceller *Create();
static std::unique_ptr<SocketSelectCanceller> Create();
};
class NetworkSocket
@ -135,9 +135,9 @@ public:
this->timeout = timeout;
};
static NetworkSocket *Create(NetworkProtocol protocol);
static std::shared_ptr<NetworkSocket> Create(NetworkProtocol protocol);
static NetworkAddress ResolveDomainName(std::string name);
static bool Select(std::vector<NetworkSocket *> &readFds, std::vector<NetworkSocket *> &writeFds, std::vector<NetworkSocket *> &errorFds, SocketSelectCanceller *canceller);
static bool Select(std::vector<std::shared_ptr<NetworkSocket>> &readFds, std::vector<std::shared_ptr<NetworkSocket>> &writeFds, std::vector<std::shared_ptr<NetworkSocket>> &errorFds, const std::unique_ptr<SocketSelectCanceller> &canceller);
protected:
virtual uint16_t GenerateLocalPort();
@ -159,7 +159,7 @@ class NetworkSocketWrapper : public NetworkSocket
public:
NetworkSocketWrapper(NetworkProtocol protocol) : NetworkSocket(protocol){};
virtual ~NetworkSocketWrapper(){};
virtual NetworkSocket *GetWrapped() = 0;
virtual std::shared_ptr<NetworkSocket> GetWrapped() = 0;
virtual void InitConnection() = 0;
virtual void SetNonBlocking(bool){};
};
@ -167,9 +167,9 @@ public:
class NetworkSocketTCPObfuscated : public NetworkSocketWrapper
{
public:
NetworkSocketTCPObfuscated(NetworkSocket *wrapped);
NetworkSocketTCPObfuscated(const std::shared_ptr<NetworkSocket> &wrapped);
virtual ~NetworkSocketTCPObfuscated();
virtual NetworkSocket *GetWrapped();
virtual std::shared_ptr<NetworkSocket> GetWrapped();
virtual void InitConnection();
virtual void Send(NetworkPacket packet) override;
virtual NetworkPacket Receive(size_t maxLen) override;
@ -185,7 +185,7 @@ public:
};
private:
NetworkSocket *wrapped;
std::shared_ptr<NetworkSocket> wrapped;
TCPO2State recvState;
TCPO2State sendState;
bool initialized = false;
@ -194,14 +194,14 @@ private:
class NetworkSocketSOCKS5Proxy : public NetworkSocketWrapper
{
public:
NetworkSocketSOCKS5Proxy(NetworkSocket *tcp, NetworkSocket *udp, std::string username, std::string password);
NetworkSocketSOCKS5Proxy(const std::shared_ptr<NetworkSocket> &tcp, const std::shared_ptr<NetworkSocket> &udp, std::string username, std::string password);
virtual ~NetworkSocketSOCKS5Proxy();
virtual void Send(NetworkPacket packet) override;
virtual NetworkPacket Receive(size_t maxLen) override;
virtual void Open() override;
virtual void Close();
virtual void Connect(const NetworkAddress address, uint16_t port);
virtual NetworkSocket *GetWrapped();
virtual std::shared_ptr<NetworkSocket> GetWrapped();
virtual void InitConnection();
virtual bool IsFailed();
virtual NetworkAddress GetConnectedAddress();
@ -221,8 +221,8 @@ private:
WaitingForCommandResult,
Connected
};
NetworkSocket *tcp;
NetworkSocket *udp;
std::shared_ptr<NetworkSocket> tcp;
std::shared_ptr<NetworkSocket> udp;
std::string username;
std::string password;
NetworkAddress connectedAddress = NetworkAddress::Empty();

View File

@ -605,7 +605,7 @@ void NetworkSocketPosix::SetTimeouts(int sendTimeout, int recvTimeout)
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
}
bool NetworkSocketPosix::Select(std::vector<NetworkSocket *> &readFds, std::vector<NetworkSocket *> &writeFds, std::vector<NetworkSocket *> &errorFds, SocketSelectCanceller *_canceller)
bool NetworkSocketPosix::Select(std::vector<std::shared_ptr<NetworkSocket>> &readFds, std::vector<std::shared_ptr<NetworkSocket>> &writeFds, std::vector<std::shared_ptr<NetworkSocket>> &errorFds, const std::unique_ptr<SocketSelectCanceller> &canceller)
{
fd_set readSet;
fd_set writeSet;
@ -769,3 +769,8 @@ int NetworkSocketPosix::GetDescriptorFromSocket(NetworkSocket *socket)
return GetDescriptorFromSocket(sw->GetWrapped());
return 0;
}
inline int NetworkSocketPosix::GetDescriptorFromSocket(const std::shared_ptr<NetworkSocket> &socket)
{
return GetDescriptorFromSocket(socket.get());
}

View File

@ -13,20 +13,25 @@
#include <sys/select.h>
#include <pthread.h>
namespace tgvoip {
namespace tgvoip
{
class SocketSelectCancellerPosix : public SocketSelectCanceller
{
friend class NetworkSocketPosix;
class SocketSelectCancellerPosix : public SocketSelectCanceller{
friend class NetworkSocketPosix;
public:
SocketSelectCancellerPosix();
virtual ~SocketSelectCancellerPosix();
virtual void CancelSelect();
private:
int pipeRead;
int pipeWrite;
};
class NetworkSocketPosix : public NetworkSocket{
class NetworkSocketPosix : public NetworkSocket
{
public:
NetworkSocketPosix(NetworkProtocol protocol);
virtual ~NetworkSocketPosix();
@ -35,16 +40,16 @@ public:
virtual void Open() override;
virtual void Close() override;
virtual void Connect(const NetworkAddress address, uint16_t port) override;
virtual std::string GetLocalInterfaceInfo(NetworkAddress* v4addr, NetworkAddress* v6addr) override;
virtual std::string GetLocalInterfaceInfo(NetworkAddress *v4addr, NetworkAddress *v6addr) override;
virtual void OnActiveInterfaceChanged() override;
virtual uint16_t GetLocalPort() override;
static std::string V4AddressToString(uint32_t address);
static std::string V6AddressToString(const unsigned char address[16]);
static uint32_t StringToV4Address(std::string address);
static void StringToV6Address(std::string address, unsigned char* out);
static void StringToV6Address(std::string address, unsigned char *out);
static NetworkAddress ResolveDomainName(std::string name);
static bool Select(std::vector<NetworkSocket*>& readFds, std::vector<NetworkSocket*>& writeFds, std::vector<NetworkSocket*>& errorFds, SocketSelectCanceller* canceller);
static bool Select(std::vector<std::shared_ptr<NetworkSocket>> &readFds, std::vector<std::shared_ptr<NetworkSocket>> &writeFds, std::vector<std::shared_ptr<NetworkSocket>> &errorFds, const std::unique_ptr<SocketSelectCanceller> &canceller);
virtual NetworkAddress GetConnectedAddress() override;
@ -57,19 +62,20 @@ protected:
virtual void SetMaxPriority() override;
private:
static int GetDescriptorFromSocket(NetworkSocket* socket);
static int GetDescriptorFromSocket(NetworkSocket *socket);
static int GetDescriptorFromSocket(const std::shared_ptr<NetworkSocket> &socket);
std::atomic<int> fd;
bool needUpdateNat64Prefix;
bool nat64Present;
double switchToV6at;
bool isV4Available;
std::atomic<bool> closing;
NetworkAddress tcpConnectedAddress=NetworkAddress::Empty();
NetworkAddress tcpConnectedAddress = NetworkAddress::Empty();
uint16_t tcpConnectedPort;
NetworkPacket pendingOutgoingPacket=NetworkPacket::Empty();
Buffer recvBuffer=Buffer(2048);
NetworkPacket pendingOutgoingPacket = NetworkPacket::Empty();
Buffer recvBuffer = Buffer(2048);
};
}
} // namespace tgvoip
#endif //LIBTGVOIP_NETWORKSOCKETPOSIX_H

View File

@ -693,7 +693,7 @@ void NetworkSocketWinsock::SetTimeouts(int sendTimeout, int recvTimeout)
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));
}
bool NetworkSocketWinsock::Select(std::vector<NetworkSocket *> &readFds, std::vector<NetworkSocket *> &writeFds, std::vector<NetworkSocket *> &errorFds, SocketSelectCanceller *_canceller)
bool NetworkSocketWinsock::Select(std::vector<std::shared_ptr<NetworkSocket>> &readFds, std::vector<std::shared_ptr<NetworkSocket>> &writeFds, std::vector<std::shared_ptr<NetworkSocket>> &errorFds, const std::unique_ptr<SocketSelectCanceller> &canceller)
{
fd_set readSet;
fd_set errorSet;
@ -843,3 +843,8 @@ int NetworkSocketWinsock::GetDescriptorFromSocket(NetworkSocket *socket)
return GetDescriptorFromSocket(sw->GetWrapped());
return 0;
}
inline int NetworkSocketWinsock::GetDescriptorFromSocket(const std::unique_ptr<NetworkSocket> &socket)
{
return GetDescriptorFromSocket(socket.get());
}

View File

@ -11,20 +11,25 @@
#include <stdint.h>
#include <vector>
namespace tgvoip {
namespace tgvoip
{
class Buffer;
class SocketSelectCancellerWin32 : public SocketSelectCanceller{
friend class NetworkSocketWinsock;
class SocketSelectCancellerWin32 : public SocketSelectCanceller
{
friend class NetworkSocketWinsock;
public:
SocketSelectCancellerWin32();
virtual ~SocketSelectCancellerWin32();
virtual void CancelSelect();
private:
bool canceled;
};
class NetworkSocketWinsock : public NetworkSocket{
class NetworkSocketWinsock : public NetworkSocket
{
public:
NetworkSocketWinsock(NetworkProtocol protocol);
virtual ~NetworkSocketWinsock();
@ -32,7 +37,7 @@ public:
virtual NetworkPacket Receive(size_t maxLen) override;
virtual void Open() override;
virtual void Close() override;
virtual std::string GetLocalInterfaceInfo(NetworkAddress* v4addr, NetworkAddress* v6addr) override;
virtual std::string GetLocalInterfaceInfo(NetworkAddress *v4addr, NetworkAddress *v6addr) override;
virtual void OnActiveInterfaceChanged() override;
virtual uint16_t GetLocalPort() override;
virtual void Connect(const NetworkAddress address, uint16_t port) override;
@ -40,9 +45,9 @@ public:
static std::string V4AddressToString(uint32_t address);
static std::string V6AddressToString(const unsigned char address[16]);
static uint32_t StringToV4Address(std::string address);
static void StringToV6Address(std::string address, unsigned char* out);
static void StringToV6Address(std::string address, unsigned char *out);
static NetworkAddress ResolveDomainName(std::string name);
static bool Select(std::vector<NetworkSocket*>& readFds, std::vector<NetworkSocket*>& writeFds, std::vector<NetworkSocket*>& errorFds, SocketSelectCanceller* canceller);
static bool Select(std::vector<std::shared_ptr<NetworkSocket>> &readFds, std::vector<std::shared_ptr<NetworkSocket>> &writeFds, std::vector<std::shared_ptr<NetworkSocket>> &errorFds, const std::unique_ptr<SocketSelectCanceller> &canceller);
virtual NetworkAddress GetConnectedAddress() override;
virtual uint16_t GetConnectedPort() override;
virtual void SetTimeouts(int sendTimeout, int recvTimeout) override;
@ -52,7 +57,8 @@ protected:
virtual void SetMaxPriority();
private:
static int GetDescriptorFromSocket(NetworkSocket* socket);
static int GetDescriptorFromSocket(NetworkSocket *socket);
static int GetDescriptorFromSocket(const std::unique_ptr<NetworkSocket> &socket)
uintptr_t fd;
bool needUpdateNat64Prefix;
bool nat64Present;
@ -60,12 +66,12 @@ private:
bool isV4Available;
bool isAtLeastVista;
bool closing;
NetworkAddress tcpConnectedAddress=NetworkAddress::Empty();
NetworkAddress tcpConnectedAddress = NetworkAddress::Empty();
uint16_t tcpConnectedPort;
NetworkPacket pendingOutgoingPacket=NetworkPacket::Empty();
Buffer recvBuf=Buffer(2048);
NetworkPacket pendingOutgoingPacket = NetworkPacket::Empty();
Buffer recvBuf = Buffer(2048);
};
}
} // namespace tgvoip
#endif //LIBTGVOIP_NETWORKSOCKETWINSOCK_H

View File

@ -65,6 +65,7 @@ public:
virtual ~Thread()
{
Join();
}
void Start()
@ -271,6 +272,7 @@ public:
~Thread()
{
Join();
}
void Start()