1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-12-02 09:37:52 +01:00

Finish moving

This commit is contained in:
Daniil Gentili 2020-01-25 18:24:38 +01:00
parent cf574b320b
commit f3afe0612f
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
14 changed files with 267 additions and 260 deletions

View File

@ -3,6 +3,18 @@
using namespace tgvoip;
using namespace std;
void VoIPController::SetEncryptionKey(std::vector<uint8_t> key, bool isOutgoing)
{
memcpy(encryptionKey, key.data(), 256);
uint8_t sha1[SHA1_LENGTH];
crypto.sha1((uint8_t *)encryptionKey, 256, sha1);
memcpy(keyFingerprint, sha1 + (SHA1_LENGTH - 8), 8);
uint8_t sha256[SHA256_LENGTH];
crypto.sha256((uint8_t *)encryptionKey, 256, sha256);
memcpy(callID, sha256 + (SHA256_LENGTH - 16), 16);
this->isOutgoing = isOutgoing;
}
void VoIPController::KDF(unsigned char *msgKey, size_t x, unsigned char *aesKey, unsigned char *aesIv)
{
uint8_t sA[SHA1_LENGTH], sB[SHA1_LENGTH], sC[SHA1_LENGTH], sD[SHA1_LENGTH];

View File

@ -167,142 +167,6 @@ bool VoIPController::NeedRate()
return needRate && ServerConfig::GetSharedInstance()->GetBoolean("bad_call_rating", false);
}
void VoIPController::SetRemoteEndpoints(vector<Endpoint> endpoints, bool allowP2p, int32_t connectionMaxLayer)
{
LOGW("Set remote endpoints, allowP2P=%d, connectionMaxLayer=%u", allowP2p ? 1 : 0, connectionMaxLayer);
assert(!runReceiver);
preferredRelay = 0;
this->endpoints.clear();
didAddTcpRelays = false;
useTCP = true;
for (auto it = endpoints.begin(); it != endpoints.end(); ++it)
{
if (this->endpoints.find(it->id) != this->endpoints.end())
LOGE("Endpoint IDs are not unique!");
this->endpoints[it->id] = *it;
if (currentEndpoint == 0)
currentEndpoint = it->id;
if (it->type == Endpoint::Type::UDP_RELAY)
useTCP = false;
else if (it->type == Endpoint::Type::TCP_RELAY)
didAddTcpRelays = true;
LOGV("Adding endpoint: %s:%d, %s", it->address.ToString().c_str(), it->port, it->type == Endpoint::Type::UDP_RELAY ? "UDP" : "TCP");
}
preferredRelay = currentEndpoint;
this->allowP2p = allowP2p;
this->connectionMaxLayer = connectionMaxLayer;
if (connectionMaxLayer >= 74)
{
useMTProto2 = true;
}
AddIPv6Relays();
}
void VoIPController::SetEncryptionKey(std::vector<uint8_t> key, bool isOutgoing)
{
memcpy(encryptionKey, key.data(), 256);
uint8_t sha1[SHA1_LENGTH];
crypto.sha1((uint8_t *)encryptionKey, 256, sha1);
memcpy(keyFingerprint, sha1 + (SHA1_LENGTH - 8), 8);
uint8_t sha256[SHA256_LENGTH];
crypto.sha256((uint8_t *)encryptionKey, 256, sha256);
memcpy(callID, sha256 + (SHA256_LENGTH - 16), 16);
this->isOutgoing = isOutgoing;
}
void VoIPController::SetNetworkType(int type)
{
networkType = type;
UpdateDataSavingState();
UpdateAudioBitrateLimit();
myIPv6 = NetworkAddress::Empty();
string itfName = udpSocket->GetLocalInterfaceInfo(NULL, &myIPv6);
LOGI("set network type: %s, active interface %s", NetworkTypeToString(type).c_str(), itfName.c_str());
LOGI("Local IPv6 address: %s", myIPv6.ToString().c_str());
if (IS_MOBILE_NETWORK(networkType))
{
CellularCarrierInfo carrier = GetCarrierInfo();
if (!carrier.name.empty())
{
LOGI("Carrier: %s [%s; mcc=%s, mnc=%s]", carrier.name.c_str(), carrier.countryCode.c_str(), carrier.mcc.c_str(), carrier.mnc.c_str());
}
}
if (itfName != activeNetItfName)
{
udpSocket->OnActiveInterfaceChanged();
LOGI("Active network interface changed: %s -> %s", activeNetItfName.c_str(), itfName.c_str());
bool isFirstChange = activeNetItfName.length() == 0 && state != STATE_ESTABLISHED && state != STATE_RECONNECTING;
activeNetItfName = itfName;
if (isFirstChange)
return;
messageThread.Post([this] {
wasNetworkHandover = true;
if (currentEndpoint)
{
const Endpoint &_currentEndpoint = endpoints.at(currentEndpoint);
const Endpoint &_preferredRelay = endpoints.at(preferredRelay);
if (_currentEndpoint.type != Endpoint::Type::UDP_RELAY)
{
if (_preferredRelay.type == Endpoint::Type::UDP_RELAY)
currentEndpoint = preferredRelay;
MutexGuard m(endpointsMutex);
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)
{
Endpoint &endpoint = e.second;
if (endpoint.type == Endpoint::Type::UDP_RELAY && useTCP)
{
useTCP = false;
if (_preferredRelay.type == Endpoint::Type::TCP_RELAY)
{
preferredRelay = currentEndpoint = endpoint.id;
}
}
else if (endpoint.type == Endpoint::Type::TCP_RELAY && endpoint.socket)
{
endpoint.socket->Close();
}
endpoint.averageRTT = 0;
endpoint.rtts.Reset();
}
}
}
lastUdpPingTime = 0;
if (proxyProtocol == PROXY_SOCKS5)
InitUDPProxy();
if (allowP2p && currentEndpoint)
{
SendPublicEndpointsRequest();
}
BufferOutputStream s(4);
s.WriteInt32(dataSavingMode ? INIT_FLAG_DATA_SAVING_ENABLED : 0);
if (peerVersion < 6)
{
SendPacketReliably(PKT_NETWORK_CHANGED, s.GetBuffer(), s.GetLength(), 1, 20);
}
else
{
Buffer buf(move(s));
SendExtra(buf, EXTRA_TYPE_NETWORK_CHANGED);
}
needReInitUdpProxy = true;
selectCanceller->CancelSelect();
didSendIPv6Endpoint = false;
AddIPv6Relays();
ResetUdpAvailability();
ResetEndpointPingStats();
});
}
}
void VoIPController::SetMicMute(bool mute)
{
if (micMuted == mute)
@ -458,11 +322,6 @@ const char *VoIPController::GetVersion()
return LIBTGVOIP_VERSION;
}
int64_t VoIPController::GetPreferredRelayID()
{
return preferredRelay;
}
int VoIPController::GetLastError()
{
return lastError;
@ -728,15 +587,6 @@ void VoIPController::SetEchoCancellationStrength(int strength)
echoCanceller->SetAECStrength(strength);
}
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
void VoIPController::SetAudioDataCallbacks(std::function<void(int16_t *, size_t)> input, std::function<void(int16_t *, size_t)> output, std::function<void(int16_t *, size_t)> preproc = nullptr)
{
audioInputDataCallback = input;
audioOutputDataCallback = output;
audioPreprocDataCallback = preproc;
}
#endif
int VoIPController::GetConnectionState()
{
return state;
@ -825,6 +675,7 @@ vector<uint8_t> VoIPController::GetPersistentState()
return vector<uint8_t>(jstr, jstr + strlen(jstr));
}
void VoIPController::SetOutputVolume(float level)
{
outputVolume->SetLevel(level);
@ -846,3 +697,41 @@ void VoIPController::SetAudioOutputDuckingEnabled(bool enabled)
}
}
#endif
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
void VoIPController::SetAudioDataCallbacks(std::function<void(int16_t *, size_t)> input, std::function<void(int16_t *, size_t)> output, std::function<void(int16_t *, size_t)> preproc = nullptr)
{
audioInputDataCallback = input;
audioOutputDataCallback = output;
audioPreprocDataCallback = preproc;
}
#endif
CellularCarrierInfo VoIPController::GetCarrierInfo()
{
#if defined(__APPLE__) && TARGET_OS_IOS
return DarwinSpecific::GetCarrierInfo();
#elif defined(__ANDROID__)
CellularCarrierInfo carrier;
jni::DoWithJNI([&carrier](JNIEnv *env) {
jmethodID getCarrierInfoMethod = env->GetStaticMethodID(jniUtilitiesClass, "getCarrierInfo", "()[Ljava/lang/String;");
jobjectArray jinfo = (jobjectArray)env->CallStaticObjectMethod(jniUtilitiesClass, getCarrierInfoMethod);
if (jinfo && env->GetArrayLength(jinfo) == 4)
{
carrier.name = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 0));
carrier.countryCode = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 1));
carrier.mcc = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 2));
carrier.mnc = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 3));
}
else
{
LOGW("Failed to get carrier info");
}
});
return carrier;
#else
return CellularCarrierInfo();
#endif
}

View File

@ -241,4 +241,3 @@ void VoIPController::UpdateAudioOutputState()
}
}
}

View File

@ -0,0 +1,174 @@
#include "../../VoIPController.h"
using namespace tgvoip;
using namespace std;
#pragma mark - Bandwidth management
void VoIPController::UpdateAudioBitrateLimit()
{
if (encoder)
{
if (dataSavingMode || dataSavingRequestedByPeer)
{
maxBitrate = maxAudioBitrateSaving;
encoder->SetBitrate(initAudioBitrateSaving);
}
else if (networkType == NET_TYPE_GPRS)
{
maxBitrate = maxAudioBitrateGPRS;
encoder->SetBitrate(initAudioBitrateGPRS);
}
else if (networkType == NET_TYPE_EDGE)
{
maxBitrate = maxAudioBitrateEDGE;
encoder->SetBitrate(initAudioBitrateEDGE);
}
else
{
maxBitrate = maxAudioBitrate;
encoder->SetBitrate(initAudioBitrate);
}
encoder->SetVadMode(dataSavingMode || dataSavingRequestedByPeer);
if (echoCanceller)
echoCanceller->SetVoiceDetectionEnabled(dataSavingMode || dataSavingRequestedByPeer);
}
}
void VoIPController::UpdateDataSavingState()
{
if (config.dataSaving == DATA_SAVING_ALWAYS)
{
dataSavingMode = true;
}
else if (config.dataSaving == DATA_SAVING_MOBILE)
{
dataSavingMode = networkType == NET_TYPE_GPRS || networkType == NET_TYPE_EDGE ||
networkType == NET_TYPE_3G || networkType == NET_TYPE_HSPA || networkType == NET_TYPE_LTE || networkType == NET_TYPE_OTHER_MOBILE;
}
else
{
dataSavingMode = false;
}
LOGI("update data saving mode, config %d, enabled %d, reqd by peer %d", config.dataSaving, dataSavingMode, dataSavingRequestedByPeer);
}
double VoIPController::GetAverageRTT()
{
ENFORCE_MSG_THREAD;
if (lastSentSeq >= lastRemoteAckSeq)
{
uint32_t diff = lastSentSeq - lastRemoteAckSeq;
//LOGV("rtt diff=%u", diff);
if (diff < 32)
{
double res = 0;
int count = 0;
for (const auto &packet : recentOutgoingPackets)
{
if (packet.ackTime > 0)
{
res += (packet.ackTime - packet.sendTime);
count++;
}
}
if (count > 0)
res /= count;
return res;
}
}
return 999;
}
void VoIPController::SetNetworkType(int type)
{
networkType = type;
UpdateDataSavingState();
UpdateAudioBitrateLimit();
myIPv6 = NetworkAddress::Empty();
string itfName = udpSocket->GetLocalInterfaceInfo(NULL, &myIPv6);
LOGI("set network type: %s, active interface %s", NetworkTypeToString(type).c_str(), itfName.c_str());
LOGI("Local IPv6 address: %s", myIPv6.ToString().c_str());
if (IS_MOBILE_NETWORK(networkType))
{
CellularCarrierInfo carrier = GetCarrierInfo();
if (!carrier.name.empty())
{
LOGI("Carrier: %s [%s; mcc=%s, mnc=%s]", carrier.name.c_str(), carrier.countryCode.c_str(), carrier.mcc.c_str(), carrier.mnc.c_str());
}
}
if (itfName != activeNetItfName)
{
udpSocket->OnActiveInterfaceChanged();
LOGI("Active network interface changed: %s -> %s", activeNetItfName.c_str(), itfName.c_str());
bool isFirstChange = activeNetItfName.length() == 0 && state != STATE_ESTABLISHED && state != STATE_RECONNECTING;
activeNetItfName = itfName;
if (isFirstChange)
return;
messageThread.Post([this] {
wasNetworkHandover = true;
if (currentEndpoint)
{
const Endpoint &_currentEndpoint = endpoints.at(currentEndpoint);
const Endpoint &_preferredRelay = endpoints.at(preferredRelay);
if (_currentEndpoint.type != Endpoint::Type::UDP_RELAY)
{
if (_preferredRelay.type == Endpoint::Type::UDP_RELAY)
currentEndpoint = preferredRelay;
MutexGuard m(endpointsMutex);
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)
{
Endpoint &endpoint = e.second;
if (endpoint.type == Endpoint::Type::UDP_RELAY && useTCP)
{
useTCP = false;
if (_preferredRelay.type == Endpoint::Type::TCP_RELAY)
{
preferredRelay = currentEndpoint = endpoint.id;
}
}
else if (endpoint.type == Endpoint::Type::TCP_RELAY && endpoint.socket)
{
endpoint.socket->Close();
}
endpoint.averageRTT = 0;
endpoint.rtts.Reset();
}
}
}
lastUdpPingTime = 0;
if (proxyProtocol == PROXY_SOCKS5)
InitUDPProxy();
if (allowP2p && currentEndpoint)
{
SendPublicEndpointsRequest();
}
BufferOutputStream s(4);
s.WriteInt32(dataSavingMode ? INIT_FLAG_DATA_SAVING_ENABLED : 0);
if (peerVersion < 6)
{
SendPacketReliably(PKT_NETWORK_CHANGED, s.GetBuffer(), s.GetLength(), 1, 20);
}
else
{
Buffer buf(move(s));
SendExtra(buf, EXTRA_TYPE_NETWORK_CHANGED);
}
needReInitUdpProxy = true;
selectCanceller->CancelSelect();
didSendIPv6Endpoint = false;
AddIPv6Relays();
ResetUdpAvailability();
ResetEndpointPingStats();
});
}
}

View File

@ -25,33 +25,51 @@ shared_ptr<VoIPController::Stream> VoIPController::GetStreamByID(unsigned char i
return s;
}
CellularCarrierInfo VoIPController::GetCarrierInfo()
int64_t VoIPController::GetPreferredRelayID()
{
#if defined(__APPLE__) && TARGET_OS_IOS
return DarwinSpecific::GetCarrierInfo();
#elif defined(__ANDROID__)
CellularCarrierInfo carrier;
jni::DoWithJNI([&carrier](JNIEnv *env) {
jmethodID getCarrierInfoMethod = env->GetStaticMethodID(jniUtilitiesClass, "getCarrierInfo", "()[Ljava/lang/String;");
jobjectArray jinfo = (jobjectArray)env->CallStaticObjectMethod(jniUtilitiesClass, getCarrierInfoMethod);
if (jinfo && env->GetArrayLength(jinfo) == 4)
{
carrier.name = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 0));
carrier.countryCode = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 1));
carrier.mcc = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 2));
carrier.mnc = jni::JavaStringToStdString(env, (jstring)env->GetObjectArrayElement(jinfo, 3));
}
else
{
LOGW("Failed to get carrier info");
}
});
return carrier;
#else
return CellularCarrierInfo();
#endif
return preferredRelay;
}
void VoIPController::SetRemoteEndpoints(vector<Endpoint> endpoints, bool allowP2p, int32_t connectionMaxLayer)
{
LOGW("Set remote endpoints, allowP2P=%d, connectionMaxLayer=%u", allowP2p ? 1 : 0, connectionMaxLayer);
assert(!runReceiver);
preferredRelay = 0;
this->endpoints.clear();
didAddTcpRelays = false;
useTCP = true;
for (auto it = endpoints.begin(); it != endpoints.end(); ++it)
{
if (this->endpoints.find(it->id) != this->endpoints.end())
LOGE("Endpoint IDs are not unique!");
this->endpoints[it->id] = *it;
if (currentEndpoint == 0)
currentEndpoint = it->id;
if (it->type == Endpoint::Type::UDP_RELAY)
useTCP = false;
else if (it->type == Endpoint::Type::TCP_RELAY)
didAddTcpRelays = true;
LOGV("Adding endpoint: %s:%d, %s", it->address.ToString().c_str(), it->port, it->type == Endpoint::Type::UDP_RELAY ? "UDP" : "TCP");
}
preferredRelay = currentEndpoint;
this->allowP2p = allowP2p;
this->connectionMaxLayer = connectionMaxLayer;
if (connectionMaxLayer >= 74)
{
useMTProto2 = true;
}
AddIPv6Relays();
}
void VoIPController::AddIPv6Relays()
{
if (!myIPv6.IsEmpty() && !didAddIPv6Relays)

View File

@ -1,85 +0,0 @@
#include "../../VoIPController.h"
using namespace tgvoip;
using namespace std;
#pragma mark - Bandwidth management
void VoIPController::UpdateAudioBitrateLimit()
{
if (encoder)
{
if (dataSavingMode || dataSavingRequestedByPeer)
{
maxBitrate = maxAudioBitrateSaving;
encoder->SetBitrate(initAudioBitrateSaving);
}
else if (networkType == NET_TYPE_GPRS)
{
maxBitrate = maxAudioBitrateGPRS;
encoder->SetBitrate(initAudioBitrateGPRS);
}
else if (networkType == NET_TYPE_EDGE)
{
maxBitrate = maxAudioBitrateEDGE;
encoder->SetBitrate(initAudioBitrateEDGE);
}
else
{
maxBitrate = maxAudioBitrate;
encoder->SetBitrate(initAudioBitrate);
}
encoder->SetVadMode(dataSavingMode || dataSavingRequestedByPeer);
if (echoCanceller)
echoCanceller->SetVoiceDetectionEnabled(dataSavingMode || dataSavingRequestedByPeer);
}
}
void VoIPController::UpdateDataSavingState()
{
if (config.dataSaving == DATA_SAVING_ALWAYS)
{
dataSavingMode = true;
}
else if (config.dataSaving == DATA_SAVING_MOBILE)
{
dataSavingMode = networkType == NET_TYPE_GPRS || networkType == NET_TYPE_EDGE ||
networkType == NET_TYPE_3G || networkType == NET_TYPE_HSPA || networkType == NET_TYPE_LTE || networkType == NET_TYPE_OTHER_MOBILE;
}
else
{
dataSavingMode = false;
}
LOGI("update data saving mode, config %d, enabled %d, reqd by peer %d", config.dataSaving, dataSavingMode, dataSavingRequestedByPeer);
}
double VoIPController::GetAverageRTT()
{
ENFORCE_MSG_THREAD;
if (lastSentSeq >= lastRemoteAckSeq)
{
uint32_t diff = lastSentSeq - lastRemoteAckSeq;
//LOGV("rtt diff=%u", diff);
if (diff < 32)
{
double res = 0;
int count = 0;
for (const auto &packet : recentOutgoingPackets)
{
if (packet.ackTime > 0)
{
res += (packet.ackTime - packet.sendTime);
count++;
}
}
if (count > 0)
res /= count;
return res;
}
}
return 999;
}