2020-05-19 06:33:57 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
|
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
|
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
|
|
*/
|
|
|
|
#include "calls/calls_controller_webrtc.h"
|
|
|
|
|
|
|
|
#include "webrtc/webrtc_call_context.h"
|
|
|
|
|
|
|
|
namespace Calls {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using namespace Webrtc;
|
|
|
|
|
|
|
|
[[nodiscard]] CallConnectionDescription ConvertEndpoint(const TgVoipEndpoint &data) {
|
|
|
|
return CallConnectionDescription{
|
|
|
|
.ip = QString::fromStdString(data.host.ipv4),
|
|
|
|
.ipv6 = QString::fromStdString(data.host.ipv6),
|
|
|
|
.peerTag = QByteArray(
|
|
|
|
reinterpret_cast<const char*>(data.peerTag),
|
|
|
|
base::array_size(data.peerTag)),
|
|
|
|
.connectionId = data.endpointId,
|
|
|
|
.port = data.port,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] CallContext::Config MakeContextConfig(
|
|
|
|
const TgVoipConfig &config,
|
|
|
|
const TgVoipPersistentState &persistentState,
|
|
|
|
const std::vector<TgVoipEndpoint> &endpoints,
|
|
|
|
const TgVoipProxy *proxy,
|
|
|
|
TgVoipNetworkType initialNetworkType,
|
|
|
|
const TgVoipEncryptionKey &encryptionKey,
|
|
|
|
Fn<void(QByteArray)> sendSignalingData,
|
|
|
|
Fn<void(QImage)> displayNextFrame) {
|
|
|
|
Expects(!endpoints.empty());
|
|
|
|
|
|
|
|
auto result = CallContext::Config{
|
|
|
|
.proxy = (proxy
|
|
|
|
? ProxyServer{
|
|
|
|
.host = QString::fromStdString(proxy->host),
|
|
|
|
.username = QString::fromStdString(proxy->login),
|
|
|
|
.password = QString::fromStdString(proxy->password),
|
|
|
|
.port = proxy->port }
|
|
|
|
: ProxyServer()),
|
|
|
|
.dataSaving = (config.dataSaving != TgVoipDataSaving::Never),
|
|
|
|
.key = QByteArray(
|
|
|
|
reinterpret_cast<const char*>(encryptionKey.value.data()),
|
|
|
|
encryptionKey.value.size()),
|
|
|
|
.outgoing = encryptionKey.isOutgoing,
|
|
|
|
.primary = ConvertEndpoint(endpoints.front()),
|
2021-03-13 12:12:08 +00:00
|
|
|
.alternatives = endpoints | ranges::views::drop(
|
2020-05-19 06:33:57 +00:00
|
|
|
1
|
2021-03-13 12:12:08 +00:00
|
|
|
) | ranges::views::transform(ConvertEndpoint) | ranges::to_vector,
|
2020-05-19 06:33:57 +00:00
|
|
|
.maxLayer = config.maxApiLayer,
|
|
|
|
.allowP2P = config.enableP2P,
|
|
|
|
.sendSignalingData = std::move(sendSignalingData),
|
|
|
|
.displayNextFrame = std::move(displayNextFrame),
|
|
|
|
};
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
WebrtcController::WebrtcController(
|
|
|
|
const TgVoipConfig &config,
|
|
|
|
const TgVoipPersistentState &persistentState,
|
|
|
|
const std::vector<TgVoipEndpoint> &endpoints,
|
|
|
|
const TgVoipProxy *proxy,
|
|
|
|
TgVoipNetworkType initialNetworkType,
|
|
|
|
const TgVoipEncryptionKey &encryptionKey,
|
|
|
|
Fn<void(QByteArray)> sendSignalingData,
|
|
|
|
Fn<void(QImage)> displayNextFrame)
|
|
|
|
: _impl(std::make_unique<CallContext>(MakeContextConfig(
|
|
|
|
config,
|
|
|
|
persistentState,
|
|
|
|
endpoints,
|
|
|
|
proxy,
|
|
|
|
initialNetworkType,
|
|
|
|
encryptionKey,
|
|
|
|
std::move(sendSignalingData),
|
|
|
|
std::move(displayNextFrame)))) {
|
|
|
|
}
|
|
|
|
|
|
|
|
WebrtcController::~WebrtcController() = default;
|
|
|
|
|
|
|
|
std::string WebrtcController::Version() {
|
|
|
|
return CallContext::Version().toStdString();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string WebrtcController::version() {
|
|
|
|
return Version();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setNetworkType(TgVoipNetworkType networkType) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setMuteMicrophone(bool muteMicrophone) {
|
|
|
|
_impl->setIsMuted(muteMicrophone);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setAudioOutputGainControlEnabled(bool enabled) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setEchoCancellationStrength(int strength) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setAudioInputDevice(std::string id) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setAudioOutputDevice(std::string id) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setInputVolume(float level) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setOutputVolume(float level) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setAudioOutputDuckingEnabled(bool enabled) {
|
|
|
|
}
|
|
|
|
|
|
|
|
bool WebrtcController::receiveSignalingData(const QByteArray &data) {
|
|
|
|
return _impl->receiveSignalingData(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string WebrtcController::getLastError() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string WebrtcController::getDebugInfo() {
|
|
|
|
return _impl->getDebugInfo().toStdString();
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t WebrtcController::getPreferredRelayId() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
TgVoipTrafficStats WebrtcController::getTrafficStats() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
TgVoipPersistentState WebrtcController::getPersistentState() {
|
|
|
|
return TgVoipPersistentState{};
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setOnStateUpdated(
|
|
|
|
Fn<void(TgVoipState)> onStateUpdated) {
|
|
|
|
_stateUpdatedLifetime.destroy();
|
|
|
|
_impl->state().changes(
|
|
|
|
) | rpl::start_with_next([=](CallState state) {
|
|
|
|
onStateUpdated([&] {
|
|
|
|
switch (state) {
|
|
|
|
case CallState::Initializing: return TgVoipState::WaitInit;
|
|
|
|
case CallState::Reconnecting: return TgVoipState::Reconnecting;
|
|
|
|
case CallState::Connected: return TgVoipState::Established;
|
|
|
|
case CallState::Failed: return TgVoipState::Failed;
|
|
|
|
}
|
|
|
|
Unexpected("State value in Webrtc::CallContext::state.");
|
|
|
|
}());
|
|
|
|
}, _stateUpdatedLifetime);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebrtcController::setOnSignalBarsUpdated(
|
|
|
|
Fn<void(int)> onSignalBarsUpdated) {
|
|
|
|
}
|
|
|
|
|
|
|
|
TgVoipFinalState WebrtcController::stop() {
|
|
|
|
_impl->stop();
|
|
|
|
return TgVoipFinalState();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Calls
|