public void DiscardCallAsync(TLInputPhoneCall peer, int duration, TLPhoneCallDiscardReasonBase reason, long connectionId, Action <TLUpdatesBase> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLPhoneDiscardCall { Peer = peer, Duration = duration, Reason = reason, ConnectionId = connectionId }; const string caption = "phone.discardCall"; SendInformativeMessage <TLUpdatesBase>(caption, obj, result => { var multiPts = result as ITLMultiPts; if (multiPts != null) { _updatesService.SetState(multiPts, caption); } else { _updatesService.ProcessUpdates(result, true); } callback?.Invoke(result); }, faultCallback); }
public void SetCallRatingAsync(TLInputPhoneCall peer, int rating, string comment, Action <TLUpdatesBase> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLPhoneSetCallRating { Peer = peer, Rating = rating, Comment = comment }; const string caption = "phone.setCallRating"; SendInformativeMessage <TLUpdatesBase>(caption, obj, result => { var multiPts = result as ITLMultiPts; if (multiPts != null) { _updatesService.SetState(multiPts, caption); } else { _updatesService.ProcessUpdates(result, true); } callback?.Invoke(result); }, faultCallback); }
public void ReceivedCallAsync(TLInputPhoneCall peer, Action <TLBool> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLReceivedCall { Peer = peer }; SendInformativeMessage("phone.receivedCall", obj, callback, faultCallback); }
public void ConfirmCallAsync(TLInputPhoneCall peer, TLString ga, TLLong keyFingerprint, TLPhoneCallProtocol protocol, Action <TLPhonePhoneCall> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLConfirmCall { Peer = peer, GA = ga, KeyFingerprint = keyFingerprint, Protocol = protocol }; SendInformativeMessage("phone.confirmCall", obj, callback, faultCallback); }
public void AcceptCallAsync(TLInputPhoneCall peer, TLString gb, TLPhoneCallProtocol protocol, Action <TLPhonePhoneCall> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLAcceptCall { Peer = peer, GB = gb, Protocol = protocol }; SendInformativeMessage("phone.acceptCall", obj, callback, faultCallback); }
public void SaveCallDebugAsync(TLInputPhoneCall peer, TLDataJSON debug, Action <TLBool> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLSaveCallDebug { Peer = peer, Debug = debug }; SendInformativeMessage("phone.saveCallDebug", obj, callback, faultCallback); }
public void SaveCallDebugAsync(TLInputPhoneCall peer, TLDataJSON debug, Action <bool> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLPhoneSaveCallDebug { Peer = peer, Debug = debug }; const string caption = "phone.saveCallDebug"; SendInformativeMessage(caption, obj, callback, faultCallback); }
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); }
public void ConfirmCallAsync(TLInputPhoneCall peer, byte[] ga, long fingerprint, Action <TLPhonePhoneCall> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLPhoneConfirmCall { Peer = peer, GA = ga, KeyFingerprint = fingerprint, Protocol = GetPhoneCallProtocol() }; const string caption = "phone.confirmCall"; SendInformativeMessage(caption, obj, callback, faultCallback); }
public void AcceptCallAsync(TLInputPhoneCall peer, byte[] gb, Action <TLPhonePhoneCall> callback, Action <TLRPCError> faultCallback = null) { var obj = new TLPhoneAcceptCall { Peer = peer, GB = gb, Protocol = GetPhoneCallProtocol() }; const string caption = "phone.acceptCall"; SendInformativeMessage(caption, obj, callback, faultCallback); }
private void ProcessAcceptedCall(TLPhoneCallAccepted phoneCallAccepted) { DispatchStateChanged(PhoneCallState.STATE_EXCHANGING_KEYS); if (!TLUtils.CheckGaAndGb(phoneCallAccepted.GB.Data, _secretP.Data)) { CallFailed(); return; } _authKey = MTProtoService.GetAuthKey(_aOrB, phoneCallAccepted.GB.ToBytes(), _secretP.ToBytes()); var keyHash = Utils.ComputeSHA1(_authKey); var keyFingerprint = new TLLong(BitConverter.ToInt64(keyHash, 12)); var peer = new TLInputPhoneCall { Id = phoneCallAccepted.Id, AccessHash = phoneCallAccepted.AccessHash }; var protocol = new TLPhoneCallProtocol { Flags = new TLInt(0), UdpP2P = true, UdpReflector = true, MinLayer = new TLInt(CALL_MIN_LAYER), MaxLayer = new TLInt(CALL_MAX_LAYER) }; _mtProtoService.ConfirmCallAsync(peer, TLString.FromBigEndianData(_ga), keyFingerprint, protocol, result => { _call = result; InitiateActualEncryptedCall(); }, error => { CallFailed(); }); }
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); } } } }
// This method is called when the incoming call processing is complete private void OnIncomingCallDialogDismissed(long callId, long callAccessHash, bool rejected) { Debug.WriteLine("[IncomingCallAgent] Incoming call processing is now complete."); if (rejected) { var deviceInfoService = new Telegram.Api.Services.DeviceInfo.DeviceInfoService(GetInitConnection(), true, "BackgroundDifferenceLoader", 1); var cacheService = new MockupCacheService(); var updatesService = new MockupUpdatesService(); var transportService = new TransportService(); var connectionService = new ConnectionService(deviceInfoService); var publicConfigService = new MockupPublicConfigService(); var manualResetEvent = new ManualResetEvent(false); var mtProtoService = new MTProtoService(deviceInfoService, updatesService, cacheService, transportService, connectionService, publicConfigService); mtProtoService.Initialized += (o, e) => { var peer = new TLInputPhoneCall { Id = new TLLong(callId), AccessHash = new TLLong(callAccessHash) }; var getStateAction = new TLDiscardCall { Peer = peer, Duration = new TLInt(0), Reason = new TLPhoneCallDiscardReasonBusy(), ConnectionId = new TLLong(0) }; var actions = new List <TLObject> { getStateAction }; mtProtoService.SendActionsAsync(actions, (request, result) => { manualResetEvent.Set(); }, error => { manualResetEvent.Set(); }); }; mtProtoService.InitializationFailed += (o, e) => { manualResetEvent.Set(); }; mtProtoService.Initialize(); #if DEBUG manualResetEvent.WaitOne(); #else manualResetEvent.WaitOne(TimeSpan.FromSeconds(10.0)); #endif mtProtoService.Stop(); } this.Complete(); }