danbarua / NEventSocket

A reactive FreeSwitch eventsocket library for Modern .Net
Mozilla Public License 2.0
74 stars 37 forks source link

Hangup detection #36

Closed mguerrieri closed 8 years ago

mguerrieri commented 8 years ago

I am having an issue where hang up is not being detected. I have added a class to your Examples project, based on your VoiceBlaster sample, which simply dials an internal station (VOIP softphone), plays a tone on answer, and then simply looks for a hang up. Hanging up the softphone seems to do nothing and I am at a loss. I don't know if I am doing something wrong, or if there is some issue detecting the hang up. If I just dial a number via the softphone and answer that call, then hang up the softphone, FreeSWITCH detects the hang up and ends the call, so I know that at least my basic setup seems ok. Any help would be greatly appreciated. Below is the class I added to the examples:

namespace NEventSocket.Examples.Examples
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reactive.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using ColoredConsole;
    using Net.CommandLine;
    using NEventSocket.FreeSwitch;

    public class MyTest : ICommandLineTask, IDisposable
    {
        private int currentCallCount = 0;

        public async Task Run(CancellationToken cancellationToken)
        {
            var ourCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            using (var client = await InboundSocket.Connect())
            {
                Console.WriteLine("Authenticated!");

                await client.SubscribeEvents(EventName.ChannelHangup, EventName.BackgroundJob);

                client.Events.Where(x => x.EventName == EventName.ChannelHangup)
                    .Subscribe(x => { Console.WriteLine($"Hangup Detected : {x.GetVariable("ccs_station_id")} {x.HangupCause}"); });

                using (var listener = new OutboundListener(8084))
                {
                    listener.Connections.Subscribe(
                        async socket =>
                            {
                                try
                                {
                                    await socket.Connect();

                                    var uuid = socket.ChannelData.UUID;

                                    await socket.Filter(HeaderNames.UniqueId, uuid);

                                    Console.WriteLine($"OutboundSocket connected for channel {uuid} {socket.ChannelData.GetVariable("ccs_station_id")}");

                                    await socket.ExecuteApplication(uuid, "pre_answer");
                                    await socket.Play(uuid, "{loops=2}tone_stream://%(300,25,440)");
                                    await socket.ExecuteApplication(uuid, "answer");
                                }
                                catch (OperationCanceledException)
                                {
                                    //hangup - freeswitch disconnected from us
                                }
                            });

                    listener.Start();

                    var checkCallCount = new Task(
                        async () =>
                            {
                                try
                                {
                                    while (!ourCancellationToken.IsCancellationRequested)
                                    {
                                        var res = await client.SendApi("show calls count");
                                        Console.WriteLine("Current Calls Count " + Convert.ToInt32(res.BodyText.Split(' ')[0]));
                                        currentCallCount = Convert.ToInt32(res.BodyText.Split(' ')[0]);
                                        await Task.Delay(5000);
                                    }
                                }
                                catch (OperationCanceledException)
                                {
                                    //shutdown
                                }
                            });

                    checkCallCount.Start();

                    try
                    {
                        await RegisterAgent(client, "1001");
                    }
                    catch (OperationCanceledException)
                    {
                        //shutdown
                    }

                    ColorConsole.WriteLine("Press [Enter] to exit.".Green());
                    await Util.WaitForEnterKeyPress(cancellationToken);
                    ourCancellationToken.Cancel();

                    listener.Dispose();
                }
            }
        }

        private async Task RegisterAgent(InboundSocket client, string stationId)
        {
            Console.WriteLine("Registering agent : " + stationId);

            var originateOptions = new OriginateOptions
            {
                CallerIdNumber = "8560000000",
                CallerIdName = "My CID",
                HangupAfterBridge = false,
                IgnoreEarlyMedia = true,
                TimeoutSeconds = 20
            };

            originateOptions.ChannelVariables["ccs_station_id"] = stationId;

            var originateResult =
                                    await
                                    client.Originate(
                                        $"user/{stationId}",
                                        originateOptions,
                                        "socket",
                                        "127.0.0.1:8084 async full");

            if (!originateResult.Success)
            {
                Console.WriteLine($"Registration failed to initiate : {stationId} {originateResult.ResponseText}");
            }
            else
            {
                Console.WriteLine($"Agent successfully registered : {stationId}");
            }
        }

        public void Dispose()
        {
        }
    }
}
danbarua commented 8 years ago

You need to call .SubscribeEvents() on the outbound socket to receive the hangup event:

listener.Connections.Subscribe(
                        async socket =>
                            {
                                try
                                {
                                    await socket.Connect();

                                    var uuid = socket.ChannelData.UUID;
                                    await client.SubscribeEvents(EventName.ChannelHangup);
                                    await socket.Filter(HeaderNames.UniqueId, uuid);

                                    Console.WriteLine($"OutboundSocket connected for channel {uuid} {socket.ChannelData.GetVariable("ccs_station_id")}");

                                    await socket.ExecuteApplication(uuid, "pre_answer");
                                    await socket.Play(uuid, "{loops=2}tone_stream://%(300,25,440)");
                                    await socket.ExecuteApplication(uuid, "answer");
                                }
                                catch (OperationCanceledException)
                                {
                                    //hangup - freeswitch disconnected from us
                                }
                            });
mguerrieri commented 8 years ago

Added the following after socket.Connect() and it still does not detect hang up unless I explicitly call socket.Hangup() (in which case now both the inbound and outbound sockets get an event):

                                await socket.SubscribeEvents(EventName.ChannelHangup);
                                socket.Events.Where(x => x.EventName == EventName.ChannelHangup)
                                    .Subscribe(x => { Console.WriteLine($"OB Hangup Detected : {x.GetVariable("ccs_station_id")} {x.HangupCause}"); });

It almost seems like FreeSWITCH is not even generating a hang up event when I hang up the softphone, but that doesn't make a whole lot of sense to me...

danbarua commented 8 years ago

That doesn’t make sense at all, the next step is to plug in a logging lib (I use NLog) and grab some Trace level logs to a file and post it up here.

Dan Barua

On Friday, 20 May 2016 at 19:10, Mark Guerrieri wrote:

Added the following after socket.Connect() and it still does not detect hang up unless I explicitly call socket.Hangup() (in which case now both the inbound and outbound sockets get an event): await socket.SubscribeEvents(EventName.ChannelHangup); socket.Events.Where(x => x.EventName == EventName.ChannelHangup) .Subscribe(x => { Console.WriteLine($"OB Hangup Detected : {x.GetVariable("ccs_station_id")} {x.HangupCause}"); });
It almost seems like FreeSWITCH is not even generating a hang up event when I hang up the softphone, but that doesn't make a whole lot of sense to me...

— You are receiving this because you commented. Reply to this email directly or view it on GitHub (https://github.com/danbarua/NEventSocket/issues/36#issuecomment-220678827)

mguerrieri commented 8 years ago

You are right- it didn't make sense. The issue was that the softphone sends the SIP BYE command to the media server, NOT to the switch, and the media server was blocking the port my soft phone was sending on. The soft phone has an option to send all SIP messages directly to the switch, which solved the problem. False alarm, sorry!

danbarua commented 8 years ago

I was going to say, it was most likely a topology/NAT issue. Glad you got it sorted.