From 8a4a7897a0d2902b83a22a0e01080a7d3294c32c Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 10 May 2017 10:58:02 +0300 Subject: [PATCH] Fix contract violation in Call::startIncoming. Also fix call answer while dhConfig is not received yet. --- Telegram/SourceFiles/calls/calls_call.cpp | 17 ++++++++++++++--- Telegram/SourceFiles/calls/calls_call.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index be264ba26d..72e2ddb33b 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -121,19 +121,21 @@ void Call::start(base::const_byte_span random) { t_assert(!_dhConfig.p.empty()); generateModExpFirst(random); - if (_state != State::Failed && _state != State::FailedHangingUp) { + if (_state == State::Starting || _state == State::Requesting) { if (_type == Type::Outgoing) { startOutgoing(); } else { startIncoming(); } + } else if (_state == State::ExchangingKeys && _answerAfterDhConfigReceived) { + answer(); } } void Call::startOutgoing() { Expects(_type == Type::Outgoing); + Expects(_state == State::Requesting); - setState(State::Requesting); request(MTPphone_RequestCall(_user->inputUser, MTP_int(rand_value()), MTP_bytes(_gaHash), MTP_phoneCallProtocol(MTP_flags(MTPDphoneCallProtocol::Flag::f_udp_p2p | MTPDphoneCallProtocol::Flag::f_udp_reflector), MTP_int(kMinLayer), MTP_int(kMaxLayer)))).done([this](const MTPphone_PhoneCall &result) { Expects(result.type() == mtpc_phone_phoneCall); @@ -184,9 +186,17 @@ void Call::answer() { Expects(_type == Type::Incoming); if (_state != State::Starting && _state != State::WaitingIncoming) { - return; + if (_state != State::ExchangingKeys || !_answerAfterDhConfigReceived) { + return; + } } setState(State::ExchangingKeys); + if (_gb.empty()) { + _answerAfterDhConfigReceived = true; + return; + } else { + _answerAfterDhConfigReceived = false; + } request(MTPphone_AcceptCall(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_bytes(_gb), _protocol)).done([this](const MTPphone_PhoneCall &result) { Expects(result.type() == mtpc_phone_phoneCall); auto &call = result.c_phone_phoneCall(); @@ -234,6 +244,7 @@ void Call::redial() { t_assert(_controller == nullptr); _type = Type::Outgoing; setState(State::Requesting); + _answerAfterDhConfigReceived = false; startWaitingTrack(); _delegate->callRedial(this); } diff --git a/Telegram/SourceFiles/calls/calls_call.h b/Telegram/SourceFiles/calls/calls_call.h index 1045bf626e..958421e11f 100644 --- a/Telegram/SourceFiles/calls/calls_call.h +++ b/Telegram/SourceFiles/calls/calls_call.h @@ -161,6 +161,7 @@ private: Type _type = Type::Outgoing; State _state = State::Starting; FinishType _finishAfterRequestingCall = FinishType::None; + bool _answerAfterDhConfigReceived = false; base::Observable _stateChanged; TimeMs _startTime = 0; base::DelayedCallTimer _finishByTimeoutTimer;