Ejemplo n.º 1
0
        private static Task <bool> PlaceCall(CancellationToken cancel)
        {
            // Set up a default SIP transport.
            var sipTransport = new SIPTransport();
            //EnableTraceLogs(sipTransport);

            var targetUri         = SIPURI.ParseSIPURI(TARGET_DST);
            int requestedDtmfCode = Crypto.GetRandomInt(4);

            targetUri.User = requestedDtmfCode.ToString();

            SIPUserAgent ua = new SIPUserAgent(sipTransport, null, true);
            CallRecord   cr = new CallRecord {
                UA = ua, RequestedDtmfCode = requestedDtmfCode, ReceivedDtmfCode = ""
            };

            TaskCompletionSource <bool> dtmfComplete = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            // Place an outgoing call.
            ua.ClientCallTrying   += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}.");
            ua.ClientCallRinging  += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}.");
            ua.ClientCallFailed   += (uac, err, resp) => Log.LogWarning($"{uac.CallDescriptor.To} Failed: {err}, Status code: {resp?.StatusCode}");
            ua.ClientCallAnswered += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");
            ua.OnDtmfTone         += (key, duration) =>
            {
                cr.ReceivedDtmfCode = cr.ReceivedDtmfCode.Insert(0, key.ToString());
                Log.LogInformation($"Received DTMF tone {key} {cr.ReceivedDtmfCode}.");

                if (cr.ReceivedDtmfCode == cr.RequestedDtmfCode.ToString())
                {
                    dtmfComplete.SetResult(true);
                }
            };
            //ua.OnRtpEvent += (evt, hdr) => Log.LogDebug($"transferee rtp event {evt.EventID}, ssrc {hdr.SyncSource}, duration {evt.Duration}, end of event {evt.EndOfEvent}, timestamp {hdr.Timestamp}, marker {hdr.MarkerBit}.");
            ua.OnCallHungup += (dialog) => Log.LogDebug("Call hungup by remote party.");

            var  rtpSession = CreateRtpSession();
            var  callTask   = ua.Call(targetUri.ToString(), null, null, rtpSession);
            bool dtmfResult = false;

            bool didComplete = Task.WaitAll(new Task[] { callTask }, TIMEOUT_MILLISECONDS, cancel);

            if (!didComplete || !callTask.Result)
            {
                Log.LogWarning($"Call to {targetUri} failed.");
            }
            else
            {
                Log.LogInformation($"Call to {targetUri} was successful.");
                _calls.TryAdd(ua.Dialogue.CallId, cr);

                if (Task.WaitAll(new Task[] { dtmfComplete.Task }, TIMEOUT_MILLISECONDS, cancel))
                {
                    dtmfResult = dtmfComplete.Task.Result;
                }
                else
                {
                    Log.LogWarning("Timeout waiting for DTMF task to complete.");
                }

                ua.Hangup();
            }

            return(Task.FromResult(dtmfResult));
            //return Task.FromResult(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Process user key presses.
        /// </summary>
        /// <param name="exit">The cancellation token to set if the user requests to quit the application.</param>
        private static void OnKeyPress(CancellationTokenSource exitCts)
        {
            try
            {
                while (!exitCts.IsCancellationRequested)
                {
                    var keyProps = Console.ReadKey();

                    if (keyProps.KeyChar == 'c')
                    {
                        // Set up a default SIP transport.
                        var sipTransport = new SIPTransport();
                        //EnableTraceLogs(sipTransport);

                        var targetUri         = SIPURI.ParseSIPURI(TARGET_DST);
                        int requestedDtmfCode = Crypto.GetRandomInt(4);
                        targetUri.User = requestedDtmfCode.ToString();

                        SIPUserAgent ua = new SIPUserAgent(sipTransport, null, true);
                        CallRecord   cr = new CallRecord {
                            UA = ua, RequestedDtmfCode = requestedDtmfCode, ReceivedDtmfCode = ""
                        };

                        // Place an outgoing call.
                        ua.ClientCallTrying   += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Trying: {resp.StatusCode} {resp.ReasonPhrase}.");
                        ua.ClientCallRinging  += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Ringing: {resp.StatusCode} {resp.ReasonPhrase}.");
                        ua.ClientCallFailed   += (uac, err, resp) => Log.LogWarning($"{uac.CallDescriptor.To} Failed: {err}, Status code: {resp?.StatusCode}");
                        ua.ClientCallAnswered += (uac, resp) => Log.LogInformation($"{uac.CallDescriptor.To} Answered: {resp.StatusCode} {resp.ReasonPhrase}.");
                        ua.OnDtmfTone         += (key, duration) =>
                        {
                            cr.ReceivedDtmfCode = cr.ReceivedDtmfCode.Insert(0, key.ToString());
                            Log.LogInformation($"Received DTMF tone {key} {cr.ReceivedDtmfCode}.");
                        };
                        //ua.OnRtpEvent += (evt, hdr) => Log.LogDebug($"transferee rtp event {evt.EventID}, ssrc {hdr.SyncSource}, duration {evt.Duration}, end of event {evt.EndOfEvent}, timestamp {hdr.Timestamp}, marker {hdr.MarkerBit}.");
                        ua.OnCallHungup += (dialog) => Log.LogDebug("Call hungup by remote party.");

                        Task.Run(async() =>
                        {
                            var rtpSession = CreateRtpSession();
                            var callResult = await ua.Call(targetUri.ToString(), null, null, rtpSession);

                            if (!callResult)
                            {
                                Log.LogWarning($"Call to {targetUri} failed.");
                            }
                            else
                            {
                                Log.LogInformation($"Call to {targetUri} was successful.");
                                _calls.TryAdd(ua.Dialogue.CallId, cr);
                            }
                        });
                    }
                    else if (keyProps.KeyChar == 'h')
                    {
                        if (_calls.Count == 0)
                        {
                            Log.LogWarning("There are no active calls.");
                        }
                        else
                        {
                            var oldestCall = _calls.OrderBy(x => x.Value.UA.Dialogue.Inserted).First();
                            Log.LogInformation($"Hanging up call {oldestCall.Key}.");
                            oldestCall.Value.UA.OnCallHungup -= OnHangup;
                            oldestCall.Value.UA.Hangup();
                            _calls.TryRemove(oldestCall.Key, out _);
                        }
                    }
                    else if (keyProps.KeyChar == 'H')
                    {
                        if (_calls.Count == 0)
                        {
                            Log.LogWarning("There are no active calls.");
                        }
                        else
                        {
                            foreach (var call in _calls)
                            {
                                Log.LogInformation($"Hanging up call {call.Key}.");
                                call.Value.UA.OnCallHungup -= OnHangup;
                                call.Value.UA.Hangup();
                            }
                            _calls.Clear();
                        }
                    }
                    else if (keyProps.KeyChar == 'l')
                    {
                        if (_calls.Count == 0)
                        {
                            Log.LogInformation("There are no active calls.");
                        }
                        else
                        {
                            Log.LogInformation("Current call list:");
                            foreach (var call in _calls)
                            {
                                int  duration = Convert.ToInt32(DateTimeOffset.Now.Subtract(call.Value.UA.Dialogue.Inserted).TotalSeconds);
                                uint rtpSent  = (call.Value.UA.MediaSession as RtpAudioSession).RtpPacketsSent;
                                uint rtpRecv  = (call.Value.UA.MediaSession as RtpAudioSession).RtpPacketsReceived;
                                Log.LogInformation($"{call.Key}: {call.Value.UA.Dialogue.RemoteTarget}, req code {call.Value.RequestedDtmfCode}, recvd code {call.Value.ReceivedDtmfCode}, dur {duration}s, rtp sent/recvd {rtpSent}/{rtpRecv}");
                            }
                        }
                    }
                    else if (keyProps.KeyChar == 'q')
                    {
                        // Quit application.
                        Log.LogInformation("Quitting");
                        exitCts.Cancel();
                        break;
                    }
                }
            }
            catch (Exception excp)
            {
                Log.LogError($"Exception OnKeyPress. {excp.Message}.");
            }
        }