public void ReceivedCallAsync(TLInputPhoneCall peer, Action <bool> callback, Action <TLRPCError> faultCallback = null)
        {
            var obj = new TLPhoneReceivedCall {
                Peer = peer
            };

            const string caption = "phone.receivedCall";

            SendInformativeMessage(caption, obj, callback, faultCallback);
        }
Example #2
0
        private async void ProcessUpdates()
        {
            while (_queue.Count > 0)
            {
                var update = _queue.Dequeue();

                _phoneCall = update.PhoneCall;

                if (update.PhoneCall is TLPhoneCallRequested requested)
                {
                    _peer = requested.ToInputPhoneCall();

                    var req = new TLPhoneReceivedCall {
                        Peer = new TLInputPhoneCall {
                            Id = requested.Id, AccessHash = requested.AccessHash
                        }
                    };

                    const string caption  = "phone.receivedCall";
                    var          response = await SendRequestAsync <bool>(caption, req);

                    var responseUser = await SendRequestAsync <TLUser>("voip.getUser", new TLPeerUser { UserId = requested.AdminId });

                    if (responseUser.Result == null)
                    {
                        return;
                    }

                    var user  = responseUser.Result;
                    var photo = new Uri("ms-appx:///Assets/Logos/Square150x150Logo/Square150x150Logo.png");
                    if (user.Photo is TLUserProfilePhoto profile && profile.PhotoSmall is TLFileLocation location)
                    {
                        var fileName = string.Format("{0}_{1}_{2}.jpg", location.VolumeId, location.LocalId, location.Secret);
                        var temp     = FileUtils.GetTempFileUri(fileName);

                        photo = temp;
                    }

                    var coordinator = VoipCallCoordinator.GetDefault();
                    var call        = coordinator.RequestNewIncomingCall("Unigram", user.FullName, user.DisplayName, photo, "Unigram", null, "Unigram", null, VoipPhoneCallMedia.Audio, TimeSpan.FromSeconds(128));

                    _user       = user;
                    _outgoing   = false;
                    _systemCall = call;
                    _systemCall.AnswerRequested += OnAnswerRequested;
                    _systemCall.RejectRequested += OnRejectRequested;
                }
                else if (update.PhoneCall is TLPhoneCallDiscarded discarded)
                {
                    if (false)
                    {
                        discarded.IsNeedRating = true;
                    }

                    if (discarded.IsNeedRating)
                    {
                        await _connection.SendMessageAsync(new ValueSet { { "caption", "voip.setCallRating" }, { "request", TLSerializationService.Current.Serialize(_peer) } });
                    }

                    if (discarded.IsNeedDebug)
                    {
                        var req = new TLPhoneSaveCallDebug();
                        req.Debug = new TLDataJSON {
                            Data = _controller.GetDebugLog()
                        };
                        req.Peer = _peer;

                        await SendRequestAsync <bool>("phone.saveCallDebug", req);
                    }

                    await UpdateStateAsync(TLPhoneCallState.Ended);

                    if (_controller != null)
                    {
                        _controller.Dispose();
                        _controller = null;
                    }

                    if (_connection != null)
                    {
                        _connection.RequestReceived -= OnRequestReceived;
                        _connection = null;
                    }

                    if (_systemCall != null)
                    {
                        try
                        {
                            _systemCall.AnswerRequested -= OnAnswerRequested;
                            _systemCall.RejectRequested -= OnRejectRequested;
                            _systemCall.NotifyCallEnded();
                            _systemCall = null;
                        }
                        catch
                        {
                            if (_deferral != null)
                            {
                                _deferral.Complete();
                            }
                        }

                        Debug.WriteLine("VoIP call disposed");
                    }
                    else if (_deferral != null)
                    {
                        _deferral.Complete();
                    }
                }
                else if (update.PhoneCall is TLPhoneCallAccepted accepted)
                {
                    await UpdateStateAsync(TLPhoneCallState.ExchangingKeys);

                    _phoneCall = accepted;

                    auth_key = computeAuthKey(accepted);

                    byte[] authKeyHash = Utils.ComputeSHA1(auth_key);
                    byte[] authKeyId   = new byte[8];
                    Buffer.BlockCopy(authKeyHash, authKeyHash.Length - 8, authKeyId, 0, 8);
                    long fingerprint = Utils.BytesToLong(authKeyId);
                    //this.authKey = authKey;
                    //keyFingerprint = fingerprint;

                    var request = new TLPhoneConfirmCall
                    {
                        GA             = g_a,
                        KeyFingerprint = fingerprint,
                        Peer           = new TLInputPhoneCall
                        {
                            Id         = accepted.Id,
                            AccessHash = accepted.AccessHash
                        },
                        Protocol = new TLPhoneCallProtocol
                        {
                            IsUdpP2p       = true,
                            IsUdpReflector = true,
                            MinLayer       = Telegram.Api.Constants.CallsMinLayer,
                            MaxLayer       = Telegram.Api.Constants.CallsMaxLayer,
                        }
                    };

                    var response = await SendRequestAsync <TLPhonePhoneCall>("phone.confirmCall", request);

                    if (response.IsSucceeded)
                    {
                        _systemCall.NotifyCallActive();
                        Handle(new TLUpdatePhoneCall {
                            PhoneCall = response.Result.PhoneCall
                        });
                    }
                }
                else if (update.PhoneCall is TLPhoneCall call)
                {
                    _phoneCall = call;

                    if (auth_key == null)
                    {
                        auth_key = computeAuthKey(call);
                        g_a      = call.GAOrB;
                    }

                    var buffer = TLUtils.Combine(auth_key, g_a);
                    var sha256 = Utils.ComputeSHA256(buffer);

                    _emojis = EncryptionKeyEmojifier.EmojifyForCall(sha256);

                    var response = await SendRequestAsync <TLDataJSON>("phone.getCallConfig", new TLPhoneGetCallConfig());

                    if (response.IsSucceeded)
                    {
                        var responseConfig = await SendRequestAsync <TLConfig>("voip.getConfig", new TLPeerUser());

                        var config = responseConfig.Result;

                        VoIPControllerWrapper.UpdateServerConfig(response.Result.Data);

                        var logFile       = ApplicationData.Current.LocalFolder.Path + "\\tgvoip.logFile.txt";
                        var statsDumpFile = ApplicationData.Current.LocalFolder.Path + "\\tgvoip.statsDump.txt";

                        if (_controller != null)
                        {
                            _controller.Dispose();
                            _controller = null;
                        }

                        _controller = new VoIPControllerWrapper();
                        _controller.SetConfig(config.CallPacketTimeoutMs / 1000.0, config.CallConnectTimeoutMs / 1000.0, DataSavingMode.Never, true, true, true, logFile, statsDumpFile);

                        SettingsHelper.CleanUp();
                        if (SettingsHelper.IsCallsProxyEnabled)
                        {
                            var server = SettingsHelper.ProxyServer ?? string.Empty;
                            var port   = SettingsHelper.ProxyPort;
                            var user   = SettingsHelper.ProxyUsername ?? string.Empty;
                            var pass   = SettingsHelper.ProxyPassword ?? string.Empty;

                            _controller.SetProxy(ProxyProtocol.SOCKS5, server, (ushort)port, user, pass);
                        }
                        else
                        {
                            _controller.SetProxy(ProxyProtocol.None, string.Empty, 0, string.Empty, string.Empty);
                        }

                        _controller.SetStateCallback(this);
                        _controller.SetEncryptionKey(auth_key, _outgoing);

                        var connection = call.Connection;
                        var endpoints  = new Endpoint[call.AlternativeConnections.Count + 1];
                        endpoints[0] = connection.ToEndpoint();

                        for (int i = 0; i < call.AlternativeConnections.Count; i++)
                        {
                            connection       = call.AlternativeConnections[i];
                            endpoints[i + 1] = connection.ToEndpoint();
                        }

                        _controller.SetPublicEndpoints(endpoints, call.Protocol.IsUdpP2p && ApplicationSettings.Current.IsPeerToPeer);
                        _controller.Start();
                        _controller.Connect();
                    }

                    //await Task.Delay(50000);

                    //var req = new TLPhoneDiscardCall { Peer = new TLInputPhoneCall { Id = call.Id, AccessHash = call.AccessHash }, Reason = new TLPhoneCallDiscardReasonHangup() };

                    //const string caption = "phone.discardCall";
                    //await SendRequestAsync<TLUpdatesBase>(caption, req);

                    //_systemCall.NotifyCallEnded();
                }
                else if (update.PhoneCall is TLPhoneCallWaiting waiting)
                {
                    _peer = waiting.ToInputPhoneCall();

                    if (_state == TLPhoneCallState.Waiting && waiting.HasReceiveDate && waiting.ReceiveDate != 0)
                    {
                        await UpdateStateAsync(TLPhoneCallState.Ringing);
                    }
                }
            }
        }
Example #3
0
        public async void Handle(TLUpdatePhoneCall update)
        {
            await VoIPConnection.Current.SendUpdateAsync(update);

            await Task.Delay(2000);

            //if (update.PhoneCall is TLPhoneCallDiscarded discarded)
            //{
            //    if (discarded.IsNeedRating)
            //    {
            //        Debugger.Break();
            //    }

            //    if (discarded.IsNeedDebug)
            //    {
            //        Debugger.Break();
            //    }
            //}

            return;

            if (update.PhoneCall is TLPhoneCallRequested callRequested)
            {
                var reqReceived = new TLPhoneReceivedCall();
                reqReceived.Peer            = new TLInputPhoneCall();
                reqReceived.Peer.Id         = callRequested.Id;
                reqReceived.Peer.AccessHash = callRequested.AccessHash;

                ProtoService.SendRequestAsync <bool>("phone.receivedCall", reqReceived, null, null);

                var user = CacheService.GetUser(callRequested.AdminId) as TLUser;

                Execute.BeginOnUIThread(async() =>
                {
                    var dialog = await TLMessageDialog.ShowAsync(user.DisplayName, "CAAAALLL", "OK", "Cancel");
                    if (dialog == Windows.UI.Xaml.Controls.ContentDialogResult.Primary)
                    {
                        var config = await ProtoService.GetDHConfigAsync(0, 256);
                        if (config.IsSucceeded)
                        {
                            var dh = config.Result;
                            if (!TLUtils.CheckPrime(dh.P, dh.G))
                            {
                                return;
                            }

                            secretP = dh.P;

                            var salt         = new byte[256];
                            var secureRandom = new SecureRandom();
                            secureRandom.NextBytes(salt);

                            a_or_b = salt;

                            var g_b = MTProtoService.GetGB(salt, dh.G, dh.P);

                            var request = new TLPhoneAcceptCall
                            {
                                GB   = g_b,
                                Peer = new TLInputPhoneCall
                                {
                                    Id         = callRequested.Id,
                                    AccessHash = callRequested.AccessHash
                                },
                                Protocol = new TLPhoneCallProtocol
                                {
                                    IsUdpP2p       = true,
                                    IsUdpReflector = true,
                                    MinLayer       = 65,
                                    MaxLayer       = 65,
                                }
                            };

                            var response = await ProtoService.SendRequestAsync <TLPhonePhoneCall>("phone.acceptCall", request);
                            if (response.IsSucceeded)
                            {
                            }
                        }
                    }
                    else
                    {
                        var req             = new TLPhoneDiscardCall();
                        req.Peer            = new TLInputPhoneCall();
                        req.Peer.Id         = callRequested.Id;
                        req.Peer.AccessHash = callRequested.AccessHash;
                        req.Reason          = new TLPhoneCallDiscardReasonHangup();

                        ProtoService.SendRequestAsync <TLPhonePhoneCall>("phone.acceptCall", req, null, null);
                    }
                });
            }
            else if (update.PhoneCall is TLPhoneCall call)
            {
                var auth_key = computeAuthKey(call);
                var g_a      = call.GAOrB;

                var buffer = TLUtils.Combine(auth_key, g_a);
                var sha256 = Utils.ComputeSHA256(buffer);

                var emoji = EncryptionKeyEmojifier.EmojifyForCall(sha256);

                var user = CacheService.GetUser(call.AdminId) as TLUser;

                Execute.BeginOnUIThread(async() =>
                {
                    var dialog = await TLMessageDialog.ShowAsync(user.DisplayName, string.Join(" ", emoji), "OK");
                });
            }
        }