/* 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(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 &endpoints, const TgVoipProxy *proxy, TgVoipNetworkType initialNetworkType, const TgVoipEncryptionKey &encryptionKey, Fn sendSignalingData, Fn 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(encryptionKey.value.data()), encryptionKey.value.size()), .outgoing = encryptionKey.isOutgoing, .primary = ConvertEndpoint(endpoints.front()), .alternatives = endpoints | ranges::views::drop( 1 ) | ranges::views::transform(ConvertEndpoint) | ranges::to_vector, .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 &endpoints, const TgVoipProxy *proxy, TgVoipNetworkType initialNetworkType, const TgVoipEncryptionKey &encryptionKey, Fn sendSignalingData, Fn displayNextFrame) : _impl(std::make_unique(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 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 onSignalBarsUpdated) { } TgVoipFinalState WebrtcController::stop() { _impl->stop(); return TgVoipFinalState(); } } // namespace Calls