2017-04-19 09:44:07 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
|
|
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
|
|
|
|
|
|
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
It is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
In addition, as a special exception, the copyright holders give permission
|
|
|
|
to link the code of portions of this program with the OpenSSL library.
|
|
|
|
|
|
|
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|
|
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|
|
|
*/
|
|
|
|
#include "calls/calls_instance.h"
|
|
|
|
|
|
|
|
#include "mtproto/connection.h"
|
|
|
|
#include "auth_session.h"
|
2017-04-19 18:06:01 +00:00
|
|
|
#include "calls/calls_call.h"
|
2017-04-19 09:44:07 +00:00
|
|
|
|
|
|
|
namespace Calls {
|
|
|
|
|
|
|
|
Instance::Instance() = default;
|
|
|
|
|
|
|
|
void Instance::startOutgoingCall(gsl::not_null<UserData*> user) {
|
2017-04-19 18:06:01 +00:00
|
|
|
if (_currentCall) {
|
2017-04-19 09:44:07 +00:00
|
|
|
return; // Already in a call.
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:06:01 +00:00
|
|
|
_currentCall = std::make_unique<Call>(getCallDelegate(), user);
|
|
|
|
request(MTPmessages_GetDhConfig(MTP_int(_dhConfig.version), MTP_int(Call::kSaltSize))).done([this, call = base::weak_unique_ptr<Call>(_currentCall)](const MTPmessages_DhConfig &result) {
|
|
|
|
if (!call) {
|
|
|
|
DEBUG_LOG(("API Warning: call was destroyed before got dhConfig."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto random = base::const_byte_span();
|
2017-04-19 09:44:07 +00:00
|
|
|
switch (result.type()) {
|
|
|
|
case mtpc_messages_dhConfig: {
|
|
|
|
auto &config = result.c_messages_dhConfig();
|
|
|
|
if (!MTP::IsPrimeAndGood(config.vp.v, config.vg.v)) {
|
|
|
|
LOG(("API Error: bad p/g received in dhConfig."));
|
2017-04-19 18:06:01 +00:00
|
|
|
callFailed(call.get());
|
2017-04-19 09:44:07 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-04-19 18:06:01 +00:00
|
|
|
_dhConfig.g = config.vg.v;
|
|
|
|
_dhConfig.p = byteVectorFromMTP(config.vp);
|
|
|
|
random = bytesFromMTP(config.vrandom);
|
2017-04-19 09:44:07 +00:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case mtpc_messages_dhConfigNotModified: {
|
|
|
|
auto &config = result.c_messages_dhConfigNotModified();
|
2017-04-19 18:06:01 +00:00
|
|
|
random = bytesFromMTP(config.vrandom);
|
|
|
|
if (!_dhConfig.g || _dhConfig.p.empty()) {
|
2017-04-19 09:44:07 +00:00
|
|
|
LOG(("API Error: dhConfigNotModified on zero version."));
|
2017-04-19 18:06:01 +00:00
|
|
|
callFailed(call.get());
|
2017-04-19 09:44:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
default: Unexpected("Type in messages.getDhConfig");
|
|
|
|
}
|
2017-04-19 18:06:01 +00:00
|
|
|
|
|
|
|
if (random.size() != Call::kSaltSize) {
|
2017-04-19 09:44:07 +00:00
|
|
|
LOG(("API Error: dhConfig random bytes wrong size: %1").arg(random.size()));
|
2017-04-19 18:06:01 +00:00
|
|
|
callFailed(call.get());
|
2017-04-19 09:44:07 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-04-19 18:06:01 +00:00
|
|
|
call->startOutgoing(random);
|
|
|
|
}).fail([this, call = base::weak_unique_ptr<Call>(_currentCall)](const RPCError &error) {
|
|
|
|
if (!call) {
|
|
|
|
DEBUG_LOG(("API Warning: call was destroyed before got dhConfig."));
|
|
|
|
return;
|
2017-04-19 09:44:07 +00:00
|
|
|
}
|
2017-04-19 18:06:01 +00:00
|
|
|
|
|
|
|
callFailed(call.get());
|
2017-04-19 09:44:07 +00:00
|
|
|
}).send();
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:06:01 +00:00
|
|
|
void Instance::callFinished(gsl::not_null<Call*> call, const MTPPhoneCallDiscardReason &reason) {
|
|
|
|
if (_currentCall.get() == call) {
|
|
|
|
_currentCall.reset();
|
|
|
|
}
|
|
|
|
}
|
2017-04-19 09:44:07 +00:00
|
|
|
|
2017-04-19 18:06:01 +00:00
|
|
|
void Instance::callFailed(gsl::not_null<Call*> call) {
|
|
|
|
if (_currentCall.get() == call) {
|
|
|
|
_currentCall.reset();
|
2017-04-19 09:44:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-19 18:06:01 +00:00
|
|
|
void Instance::handleUpdate(const MTPDupdatePhoneCall& update) {
|
|
|
|
handleCallUpdate(update.vphone_call);
|
2017-04-19 09:44:07 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 18:06:01 +00:00
|
|
|
void Instance::handleCallUpdate(const MTPPhoneCall &call) {
|
|
|
|
if (call.type() == mtpc_phoneCallRequested) {
|
|
|
|
if (_currentCall) {
|
|
|
|
// discard ?
|
|
|
|
} else {
|
|
|
|
// show call
|
|
|
|
}
|
|
|
|
} else if (!_currentCall || !_currentCall->handleUpdate(call)) {
|
|
|
|
DEBUG_LOG(("API Warning: unexpected phone call update %1").arg(call.type()));
|
|
|
|
}
|
2017-04-19 09:44:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Instance::~Instance() = default;
|
|
|
|
|
|
|
|
Instance &Current() {
|
|
|
|
return AuthSession::Current().calls();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Calls
|