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);
        }
Example #11
0
        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();
            });
        }
Example #12
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);
                    }
                }
            }
        }
        // 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();
        }