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); } } } }
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"); }); } }