175 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 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()),
 | |
| 		.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<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
 | 
