Beispiel #1
0
        public async Task can_send_command()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                listener.Connections.Subscribe(
                    async socket =>
                {
                    socket.MessagesReceived.Where(m => m.Equals("auth ClueCon"))
                    .Take(1)
                    .Subscribe(async m =>
                    {
                        await socket.SendCommandReplyOk();
                    });

                    socket.MessagesReceived.Where(m => m.StartsWith("test"))
                    .Take(1)
                    .Subscribe(
                        async m =>
                    {
                        await socket.SendCommandReplyOk();
                    });

                    await socket.Send("Content-Type: auth/request");
                });

                using (var client = await InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon"))
                {
                    var result = await client.SendCommand("test");

                    Assert.True(result.Success);
                }
            }
        }
Beispiel #2
0
        public async Task when_a_command_reply_error_is_received_in_response_to_an_application_request_it_should_return_a_failed_ApplicationResult()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                listener.Connections.Subscribe(
                    async socket =>
                {
                    socket.MessagesReceived.Where(m => m.Equals("auth ClueCon"))
                    .Take(1)
                    .Subscribe(async m =>
                    {
                        await socket.SendCommandReplyOk();
                    });

                    socket.MessagesReceived.Where(m => m.StartsWith("sendmsg"))
                    .Take(1)
                    .Subscribe(
                        async m =>
                    {
                        await socket.SendCommandReplyError("invalid session id [c1cdaeae-ebb0-4f3f-8f75-0f673bfbc046]");
                    });

                    await socket.Send("Content-Type: auth/request");
                });

                using (var client = await InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon"))
                {
                    var result = await client.Play("c1cdaeae-ebb0-4f3f-8f75-0f673bfbc046", "test.wav");

                    Assert.False(result.Success);
                }
            }
        }
Beispiel #3
0
        public void an_invalid_password_should_throw_an_InboundSocketConnectionFailedException()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                bool authRequestReceived = false;

                listener.Connections.Subscribe(
                    async socket =>
                {
                    socket.MessagesReceived.Where(m => m.StartsWith("auth"))
                    .Subscribe(async m =>
                    {
                        authRequestReceived = true;
                        await socket.SendCommandReplyError("Invalid Password");
                    });

                    await socket.Send("Content-Type: auth/request");
                });

                var aggregateException = Record.Exception(() => InboundSocket.Connect("127.0.0.1", listener.Port, "WrongPassword").Wait());
                Assert.True(authRequestReceived);
                Assert.IsType <InboundSocketConnectionFailedException>(aggregateException.InnerException);
                Assert.Equal("Invalid password when trying to connect to 127.0.0.1:" + listener.Port, aggregateException.InnerException.Message);
            }
        }
Beispiel #4
0
        private static async void CallTracking()
        {
            var client = await InboundSocket.Connect("10.10.10.36", 8021, "ClueCon");

            string uuid = null;

            client.Events.Where(x => x.EventName == EventName.ChannelAnswer)
            .Subscribe(x =>
            {
                uuid = x.UUID;
                ColorConsole.WriteLine("Channel Answer Event ".Blue(), x.UUID);
            });

            client.Events.Where(x => x.EventName == EventName.ChannelHangup)
            .Subscribe(x =>
            {
                uuid = null;
                ColorConsole.WriteLine("Channel Hangup Event ".Blue(), x.UUID);
            });

            ColorConsole.WriteLine("Press enter to hang up the current call".Green());
            Console.ReadLine();

            if (uuid != null)
            {
                ColorConsole.WriteLine("Hanging up ".Green(), uuid);
                await client.Play(uuid, "ivr/8000/ivr-call_rejected.wav");

                await client.Hangup(uuid, HangupCause.CallRejected);
            }

            client.Exit();
        }
 public void Dispose()
 {
     if (client != null)
     {
         client.Dispose();
         client = null;
     }
 }
Beispiel #6
0
 private static async void ApiTest()
 {
     using (var client = await InboundSocket.Connect("localhost", 8021, "ClueCon"))
     {
         ColorConsole.WriteLine((await client.SendApi("status")).BodyText.DarkBlue());
         ColorConsole.WriteLine((await client.SendApi("blah")).BodyText.DarkBlue());
         ColorConsole.WriteLine((await client.SendApi("status")).BodyText.DarkBlue());
     }
 }
Beispiel #7
0
 public async Task Run(CancellationToken cancellationToken)
 {
     using (var client = await InboundSocket.Connect("localhost", 8021, "ClueCon"))
     {
         ColorConsole.WriteLine((await client.SendApi("status")).BodyText.DarkBlue());
         ColorConsole.WriteLine((await client.SendApi("invalid_api_command")).BodyText.DarkRed());
         ColorConsole.WriteLine((await client.SendApi("sofia status")).BodyText.DarkBlue());
         ColorConsole.WriteLine((await client.SendApi("show bridged_calls")).BodyText.DarkBlue());
     }
 }
Beispiel #8
0
        public void when_no_AuthRequest_received_it_should_throw_TimeoutException()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                var aggregateException = Record.Exception(() => InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon", TimeSpan.FromMilliseconds(100)).Wait());
                Assert.IsType <TimeoutException>(aggregateException.InnerException);
            }
        }
Beispiel #9
0
        public async Task when_a_CHANNEL_EXECUTE_COMPLETE_event_is_returned_it_should_complete_the_Application()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                listener.Connections.Subscribe(
                    async socket =>
                {
                    socket.MessagesReceived.Where(m => m.Equals("auth ClueCon"))
                    .Take(1)
                    .Subscribe(async m =>
                    {
                        await socket.SendCommandReplyOk();
                    });

                    socket.MessagesReceived.Where(m => m.StartsWith("event"))
                    .Take(1)
                    .Subscribe(async m => await socket.SendCommandReplyOk());

                    socket.MessagesReceived.Where(m => m.StartsWith("sendmsg"))
                    .Take(1)
                    .Subscribe(
                        async m =>
                    {
                        var regex   = new Regex(@"sendmsg (?<channelUUID>\S+)\nEvent-UUID: (?<applicationUUID>\S+)\n");
                        var matches = regex.Match(m);

                        var channelUUID     = matches.Groups["channelUUID"].Value;
                        var applicationUUID = matches.Groups["applicationUUID"].Value;

                        var channelExecuteComplete =
                            TestMessages.PlaybackComplete
                            .Replace("Application-UUID: fd3ababd-ad60-4582-8c6c-609064d55fe7", "Application-UUID: " + applicationUUID)
                            .Replace("Unique-ID: 4e1cfa50-4c2f-44c9-aaf3-8ca590bed0e4", "Unique-ID: " + channelUUID)
                            .Replace("\r\n", "\n");

                        await socket.SendCommandReplyOk();
                        await socket.Send(channelExecuteComplete);
                    });

                    await socket.Send("Content-Type: auth/request");
                });

                using (var client = await InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon"))
                {
                    var result = await client.Play("4e1cfa50-4c2f-44c9-aaf3-8ca590bed0e4", "test.wav");

                    Assert.True(result.Success);
                    Assert.Equal("FILE PLAYED", result.ResponseText);
                }
            }
        }
Beispiel #10
0
        private async Task Dialler(InboundSocket client, CancellationToken ourCancellationToken)
        {
            while (!ourCancellationToken.IsCancellationRequested)
            {
                while (currentCallCount >= MAX_CALLS && !ourCancellationToken.IsCancellationRequested)
                {
                    await Task.Delay(2000);
                }

                var mobileNos = new List <string>()
                {
                    "8940703114", "8754006482"
                };

                await Task.WhenAll(
                    mobileNos.Take(MAX_CALLS).Select(
                        mobileNo => Task.Run(
                            async() =>
                {
                    Console.WriteLine("Call initiating : " + mobileNo);

                    var originateOptions = new OriginateOptions
                    {
                        CallerIdName     = "874561",
                        CallerIdNumber   = "874561",
                        IgnoreEarlyMedia = true
                    };

                    originateOptions.ChannelVariables["mobile_no"] = mobileNo;

                    var originateResult =
                        await
                        client.Originate(
                            string.Format("sofia/internal/{0}@{1}", mobileNo, GATEWAY),
                            originateOptions,
                            "socket",
                            "127.0.0.1:8084 async full");

                    if (!originateResult.Success)
                    {
                        Console.WriteLine(
                            "Call Failed to initiate : {0} {1}",
                            mobileNo,
                            originateResult.ResponseText);
                    }
                    else
                    {
                        Console.WriteLine("Call Successfully initiated {0}", mobileNo);
                    }
                })));
            }
        }
Beispiel #11
0
        public async Task when_FreeSwitch_disconnects_it_should_complete_the_observables()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                bool disconnected = false;

                listener.Connections.Subscribe(
                    async socket =>
                {
                    socket.MessagesReceived.Where(m => m.Equals("auth ClueCon"))
                    .Take(1)
                    .Subscribe(async m =>
                    {
                        await socket.SendCommandReplyOk();
                    });


                    socket.MessagesReceived.Where(m => m.StartsWith("exit"))
                    .Take(1)
                    .Subscribe(
                        async m =>
                    {
                        await socket.SendCommandReplyOk();
                        await socket.SendDisconnectNotice();
                        socket.Dispose();
                        disconnected = true;
                    });

                    await socket.Send("Content-Type: auth/request");
                });

                using (var client = await InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon"))
                {
                    bool completed = false;
                    client.Messages.Subscribe(_ => { }, ex => { }, () => completed = true);

                    await client.Exit();

                    await Wait.Until(() => disconnected);

                    Console.WriteLine("Disconnected, completed:" + completed);

                    await Wait.Until(() => completed);

                    Assert.True(completed);
                }
            }
        }
Beispiel #12
0
        public async Task when_no_api_response_received_it_should_throw_a_TimeOutException()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                bool apiRequestReceived = false;

                listener.Connections.Subscribe(
                    async socket =>
                {
                    socket.MessagesReceived.FirstAsync(m => m.Equals("auth ClueCon"))
                    .Subscribe(async m =>
                    {
                        await socket.SendCommandReplyOk();
                    });

                    socket.MessagesReceived.FirstAsync(m => m.StartsWith("api"))
                    .Subscribe(async m =>
                    {
                        apiRequestReceived = true;
                        await Task.Delay(1000);
                        await socket.SendApiResponseError("error");
                    });

                    socket.MessagesReceived.Where(m => m.Equals("exit"))
                    .Subscribe(
                        async _ =>
                    {
                        await socket.SendCommandReplyOk();
                        await socket.SendDisconnectNotice();
                    });

                    await socket.Send("Content-Type: auth/request");
                });

                using (var client = InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon", TimeSpan.FromMilliseconds(100)).Result)
                {
                    client.ResponseTimeOut = TimeSpan.FromMilliseconds(100);
                    var ex = Record.Exception(() => client.SendApi("status").Wait());

                    Assert.NotNull(ex);
                    Assert.IsType <TimeoutException>(ex.InnerException);
                    Assert.True(apiRequestReceived);

                    await client.Exit();
                }
            }
        }
Beispiel #13
0
        private static async void DtmfTest()
        {
            var client = await InboundSocket.Connect("10.10.10.36", 8021, "ClueCon");

            var originate =
                await
                client.Originate(
                    "user/1005",
                    new OriginateOptions
            {
                CallerIdNumber    = "123456789",
                CallerIdName      = "Dan Leg A",
                HangupAfterBridge = false,
                TimeoutSeconds    = 20
            });

            if (!originate.Success)
            {
                ColorConsole.WriteLine("Originate Failed ".Red(), originate.HangupCause.ToString());
                client.Exit();
            }
            else
            {
                var uuid = originate.ChannelData.UUID;
                await client.SubscribeEvents(EventName.Dtmf);

                await client.SetMultipleChannelVariables(uuid, "dtmf_verbose=true", "drop_dtmf=true");

                //"min_dup_digit_spacing_ms=500",
                //"spandsp_dtmf_rx_threshold=-32");
                //"spandsp_dtmf_rx_twist=32",
                //"spandsp_dtmf_rx_reverse_twist=7");
                await client.ExecuteApplication(uuid, "spandsp_start_dtmf");

                client.OnHangup(uuid,
                                e =>
                {
                    ColorConsole.WriteLine("Hangup Detected on A-Leg {0} {1}".Red(),
                                           e.Headers[HeaderNames.CallerUniqueId],
                                           e.Headers[HeaderNames.HangupCause]);

                    client.Exit();
                });

                client.Events.Where(x => x.UUID == uuid && x.EventName == EventName.Dtmf)
                .Subscribe(e => Console.WriteLine(e.Headers[HeaderNames.DtmfDigit]));
            }
        }
Beispiel #14
0
        public void when_no_response_to_auth_received_it_should_throw_TimeoutException()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                listener.Connections.Subscribe(
                    async socket =>
                {
                    await socket.Send("Content-Type: auth/request");
                });

                var aggregateException = Record.Exception(() => InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon", TimeSpan.FromMilliseconds(100)).Wait());
                Assert.IsType <TimeoutException>(aggregateException.InnerException);
            }
        }
Beispiel #15
0
        public static async void Run()
        {
            var client = await InboundSocket.Connect("192.168.99.66", 8021, "12345");

            var res = await client.Api("status");

            Console.WriteLine(res.BodyText);
            await client.SubscribeEvents(new EventName[] { EventName.PlaybackStop });

            client.Events.Subscribe(evnt => {
                Console.WriteLine(evnt.EventName);
                foreach (var v in evnt.Headers)
                {
                    Console.WriteLine(v.Key + " " + v.Value);
                }
                Console.WriteLine();
                Console.WriteLine();
            });
        }
Beispiel #16
0
        public async Task sending_a_correct_password_should_connect()
        {
            using (var listener = new FakeFreeSwitchListener(0))
            {
                listener.Start();

                bool authRequestReceived = false;
                bool exitRequestReceived = false;

                listener.Connections.Subscribe(
                    async socket =>
                {
                    socket.MessagesReceived.Where(m => m.Equals("auth ClueCon"))
                    .Subscribe(async m =>
                    {
                        authRequestReceived = true;
                        await socket.SendCommandReplyOk();
                    });

                    socket.MessagesReceived.Where(m => m.Equals("exit"))
                    .Subscribe(
                        async _ =>
                    {
                        exitRequestReceived = true;
                        await socket.SendCommandReplyOk();
                        await socket.SendDisconnectNotice();
                    });

                    await socket.Send("Content-Type: auth/request");
                });

                using (var client = await InboundSocket.Connect("127.0.0.1", listener.Port, "ClueCon"))
                {
                    Assert.True(authRequestReceived);

                    await client.Exit();

                    await Wait.Until(() => exitRequestReceived);

                    Assert.True(exitRequestReceived);
                }
            }
        }
Beispiel #17
0
        public Task Run(CancellationToken cancellationToken)
        {
            int authFailures       = 0;
            int heartbeatsReceived = 0;

            var settings = commandLineReader.ReadObject <LoadTestSettings>(cancellationToken);

            ColorConsole.WriteLine("Spinning up ".DarkGreen(), settings.MaxClients.ToString().Green(), " InboundSockets".DarkGreen());
            ColorConsole.WriteLine("They will connect and subscribe to HeartBeat events then disconnect when the first Heartbeat has been received.".DarkGreen());
            Parallel.For(0, settings.MaxClients,
                         async(_) =>
            {
                long clientId = 0;
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                try
                {
                    using (
                        InboundSocket client =
                            await
                            InboundSocket.Connect(
                                "127.0.0.1",
                                8021,
                                "ClueCon",
                                TimeSpan.FromSeconds(settings.ConnectionTimeoutSeconds)))
                    {
                        clientId = client.Id;
                        await client.SubscribeEvents(EventName.Heartbeat);

                        EventMessage heartbeat =
                            await client.Events.FirstOrDefaultAsync(x => x.EventName == EventName.Heartbeat).ToTask(cancellationToken);
                        if (heartbeat != null)
                        {
                            Interlocked.Increment(ref heartbeatsReceived);
                            ColorConsole.WriteLine("Client ".DarkCyan(), clientId.ToString(), " reporting in ".DarkCyan());
                        }
                    }
                }
                catch (InboundSocketConnectionFailedException ex)
                {
                    if (ex.InnerException != null && ex.InnerException is TimeoutException)
                    {
                        ColorConsole.WriteLine("Auth Timeout".OnDarkRed());
                    }
                    else
                    {
                        ColorConsole.WriteLine("Connection failure ".OnDarkRed(), ex.Message.DarkRed());
                    }
                    Interlocked.Increment(ref authFailures);
                }
                catch (TaskCanceledException)
                {
                }
            });

            ColorConsole.WriteLine("Press [Enter] to exit.".Green());
            Console.ReadLine();

            ColorConsole.WriteLine("THere were {0} heartbeats".Fmt(heartbeatsReceived).Green());
            ColorConsole.WriteLine("THere were {0} auth timeout failures".Fmt(authFailures).Red());

            return(Task.FromResult(0));
        }
Beispiel #18
0
        public async Task Run(CancellationToken cancellationToken)
        {
            client = await InboundSocket.Connect();

            Console.WriteLine("Authenticated!");

            try
            {
                await client.SubscribeEvents(EventName.Dtmf);

                var originate =
                    await
                    client.Originate(

                        "user/1000",
                        new OriginateOptions
                {
                    CallerIdNumber    = "123456789",
                    CallerIdName      = "Dan Leg A",
                    HangupAfterBridge = false,
                    TimeoutSeconds    = 20,
                });

                if (!originate.Success)
                {
                    ColorConsole.WriteLine("Originate Failed ".Red(), originate.HangupCause.ToString());
                    await client.Exit();
                }
                else
                {
                    var uuid = originate.ChannelData.Headers[HeaderNames.CallerUniqueId];

                    ColorConsole.WriteLine("Originate success ".Green(), originate.ChannelData.Headers[HeaderNames.AnswerState]);

                    var recordingPath = "{0}.wav".Fmt(uuid);
                    //"c:/temp/recording_{0}.wav".Fmt(uuid); //"$${recordings_dir}/" + "{0}.wav".Fmt(uuid); //"c:/temp/recording_{0}.wav".Fmt(uuid);

                    client.OnHangup(
                        uuid,
                        e =>
                    {
                        ColorConsole.WriteLine(
                            "Hangup Detected on A-Leg ".Red(),
                            e.Headers[HeaderNames.CallerUniqueId],
                            " ",
                            e.Headers[HeaderNames.HangupCause]);

                        client.Exit();
                    });

                    await client.Play(uuid, "ivr/ivr-call_being_transferred.wav");

                    var bridgeUUID = Guid.NewGuid().ToString();

                    var ringingHandler =
                        client.ChannelEvents.Where(x => x.UUID == bridgeUUID && x.EventName == EventName.ChannelProgress)
                        .Take(1)
                        .Subscribe(e => ColorConsole.WriteLine("Progress {0} on {1}".Fmt(e.AnswerState, e.UUID).Blue()));

                    var bridge =
                        await
                        client.Bridge(
                            uuid,
                            "user/1003",
                            new BridgeOptions()
                    {
                        UUID           = bridgeUUID,
                        TimeoutSeconds = 20,
                        //CallerIdName = "Dan B Leg",
                        //CallerIdNumber = "987654321",
                        //HangupAfterBridge = false,
                        //IgnoreEarlyMedia = true,
                        //ContinueOnFail = true,
                        //RingBack = "tone_stream://${uk-ring};loops=-1",
                        //ConfirmPrompt = "ivr/8000/ivr-to_accept_press_one.wav",
                        //ConfirmInvalidPrompt = "ivr/8000/ivr-that_was_an_invalid_entry.wav",
                        //ConfirmKey = "1234",
                    });

                    if (!bridge.Success)
                    {
                        ringingHandler.Dispose();

                        ColorConsole.WriteLine("Bridge failed ".Red(), bridge.ResponseText);

                        await client.Play(uuid, "ivr/ivr-call_rejected.wav");

                        await client.Hangup(uuid, HangupCause.CallRejected);
                    }
                    else
                    {
                        ColorConsole.WriteLine(
                            "Bridge succeeded from {0} to {1} - {2}".Fmt(bridge.ChannelData.UUID, bridge.BridgeUUID, bridge.ResponseText)
                            .Green());

                        //when b-leg hangs up, play a notification to a-leg
                        client.OnHangup(
                            bridge.BridgeUUID,
                            async e =>
                        {
                            ColorConsole.WriteLine(
                                "Hangup Detected on B-Leg ".Red(),
                                e.Headers[HeaderNames.CallerUniqueId],
                                " ",
                                e.Headers[HeaderNames.HangupCause]);

                            await client.Play(uuid, "ivr/ivr-you_may_exit_by_hanging_up.wav");
                            await client.Hangup(uuid, HangupCause.NormalClearing);
                        });

                        await client.SetChannelVariable(uuid, "RECORD_ARTIST", "'Opex Hosting Ltd'");

                        await client.SetChannelVariable(uuid, "RECORD_MIN_SEC", 0);

                        await client.SetChannelVariable(uuid, "RECORD_STEREO", "true");

                        var recordingResult = await client.SendApi("uuid_record {0} start {1}".Fmt(uuid, recordingPath));

                        ColorConsole.WriteLine(("Recording... " + recordingResult.Success).Green());

                        if (recordingResult.Success)
                        {
                            client.ChannelEvents.Where(x => x.UUID == uuid && x.EventName == EventName.Dtmf).Subscribe(
                                async(e) =>
                            {
                                var dtmf = e.Headers[HeaderNames.DtmfDigit];
                                switch (dtmf)
                                {
                                case "1":
                                    ColorConsole.WriteLine("Mask recording".Green());
                                    await client.SendApi("uuid_record {0} mask {1}".Fmt(uuid, recordingPath));
                                    await
                                    client.ExecuteApplication(
                                        uuid,
                                        "displace_session",
                                        applicationArguments: "{0} m".Fmt("ivr/ivr-recording_paused.wav"));
                                    break;

                                case "2":
                                    ColorConsole.WriteLine("Unmask recording".Green());
                                    await client.SendApi("uuid_record {0} unmask {1}".Fmt(uuid, recordingPath));
                                    await
                                    client.ExecuteApplication(
                                        uuid,
                                        "displace_session",
                                        applicationArguments: "{0} m".Fmt("ivr/ivr-begin_recording.wav"));
                                    break;

                                case "3":
                                    ColorConsole.WriteLine("Stop recording".Green());
                                    await client.SendApi("uuid_record {0} stop {1}".Fmt(uuid, recordingPath));
                                    await
                                    client.ExecuteApplication(
                                        uuid,
                                        "displace_session",
                                        applicationArguments: "{0} m".Fmt("ivr/ivr-recording_stopped.wav"));
                                    break;
                                }
                            });
                        }
                    }
                }
            }
            catch (TaskCanceledException)
            {
                ColorConsole.WriteLine("TaskCancelled - shutting down".OnRed());
                client.Dispose();
            }

            ColorConsole.WriteLine("Press [Enter] to exit.".Green());
            await Util.WaitForEnterKeyPress(cancellationToken);
        }
Beispiel #19
0
        public async Task Run(CancellationToken cancellationToken)
        {
            client = await InboundSocket.Connect("127.0.0.1", 8021, "ClueCon", TimeSpan.FromSeconds(20));

            var originate =
                await
                client.Originate(
                    "user/1000",
                    new OriginateOptions
            {
                CallerIdNumber    = "123456789",
                CallerIdName      = "Dan Leg A",
                HangupAfterBridge = false,
                TimeoutSeconds    = 20
            });

            if (!originate.Success)
            {
                ColorConsole.WriteLine("Originate Failed ".Red(), originate.HangupCause.ToString());
                await client.Exit();
            }
            else
            {
                var uuid = originate.ChannelData.UUID;
                await client.SubscribeEvents(EventName.Dtmf);

                //uncomment to play with mod_spandsp inband dtmf detection
                //note: i could not get this to work on windows, works fine on linux

                //await client.SetMultipleChannelVariables(uuid,
                //"min_dup_digit_spacing_ms=500",
                //"spandsp_dtmf_rx_threshold=-32");
                //"spandsp_dtmf_rx_twist=32",
                //"spandsp_dtmf_rx_reverse_twist=7");
                //await client.ExecuteApplication(uuid, "spandsp_start_dtmf");

                client.OnHangup(
                    uuid,
                    e =>
                {
                    ColorConsole.WriteLine(
                        "Hangup Detected on A-Leg".Red(),
                        e.Headers[HeaderNames.CallerUniqueId],
                        e.Headers[HeaderNames.HangupCause]);

                    client.Exit();
                });

                client.ChannelEvents.Where(x =>
                                           x.UUID == uuid &&
                                           x.EventName == EventName.Dtmf).Subscribe(
                    e =>
                {
                    Console.WriteLine("Got DTMF");
                    Console.WriteLine(e.UUID == uuid);
                    Console.WriteLine("UIIDS: event {0} ours {1}", e.UUID, uuid);
                    Console.WriteLine(e.Headers[HeaderNames.DtmfDigit]);
                });

                ColorConsole.WriteLine("Press [Enter] to exit.".Green());
                await Util.WaitForEnterKeyPress(cancellationToken);
            }
        }
Beispiel #20
0
        public async Task Run(CancellationToken cancellationToken)
        {
            //cancellationToken is cancelled when Ctrl+C is pressed
            //we'll use our own inner cancellationToken in our business logic
            //and link it to the outer one that is provided.
            var ourCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

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

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

                client.ChannelEvents.Where(x => x.EventName == EventName.ChannelHangup && x.HangupCause != HangupCause.NormalClearing)
                .Subscribe(x => { Console.WriteLine("Hangup Detected : {0} {1}", x.GetVariable("mobile_no"), x.HangupCause); });

                using (var listener = new OutboundListener(8084))
                {
                    listener.Connections.Subscribe(
                        async socket =>
                    {
                        try
                        {
                            await socket.Connect();
                            await socket.Filter(HeaderNames.UniqueId, socket.ChannelData.UUID);

                            var uuid = socket.ChannelData.Headers[HeaderNames.UniqueId];
                            Console.WriteLine(
                                "OutboundSocket connected for channel {0} {1}",
                                uuid,
                                socket.ChannelData.GetVariable("mobile_no"));

                            await socket.Play(uuid, "misc/8000/misc-learn_more_about_freeswitch_solutions.wav");
                            await socket.Play(uuid, "misc/8000/misc-freeswitch_is_state_of_the_art.wav");
                            await socket.ExecuteApplication(uuid, "sleep", "1000");         //wait for audio to go out to the network
                            await socket.Hangup(uuid, HangupCause.NormalClearing);
                        }
                        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(2000);
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            //shutdown
                        }
                    });

                    checkCallCount.Start();

                    Task.Run(
                        async() =>
                    {
                        try
                        {
                            await Dialler(client, ourCancellationToken.Token);
                        }
                        catch (OperationCanceledException)
                        {
                            //shutdown
                        }
                    });

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

                    ourCancellationToken.Cancel();

                    listener.Dispose();
                }
            }
        }
        public async Task Run(CancellationToken cancellationToken)
        {
            client = await InboundSocket.Connect("127.0.0.1", 8021, "ClueCon", TimeSpan.FromSeconds(20));

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

            var originate =
                await
                client.Originate(
                    "user/1000",
                    new OriginateOptions
            {
                CallerIdNumber    = "123456789",
                CallerIdName      = "Dan Leg A",
                HangupAfterBridge = false,
                TimeoutSeconds    = 20
            });

            if (!originate.Success)
            {
                ColorConsole.WriteLine("Originate Failed ".Blue(), originate.HangupCause.ToString());
                await client.Exit();
            }
            else
            {
                ColorConsole.WriteLine("{0} {1} {2}".Fmt(originate.ChannelData.EventName, originate.ChannelData.AnswerState, originate.ChannelData.ChannelState).Blue());
                var uuid = originate.ChannelData.UUID;
                await client.SetChannelVariable(uuid, "dtmf_verbose", "true");

                //await client.StartDtmf(uuid);

                client.Events.Where(x => x.UUID == uuid && x.EventName == EventName.ChannelHangup)
                .Subscribe(
                    e =>
                {
                    ColorConsole.WriteLine("Hangup Detected on A-Leg ".Red(), e.UUID, e.HangupCause.ToString());
                    client.Exit();
                });

                client.Events.Where(x => x.UUID == uuid && x.EventName == EventName.Dtmf)
                .Subscribe(e => ColorConsole.WriteLine("DTMF Detected ".Blue(), e.Headers[HeaderNames.DtmfDigit]));

                var playGetDigitsResult = await
                                          client.PlayGetDigits(
                    uuid,
                    new PlayGetDigitsOptions()
                {
                    MinDigits        = 4,
                    MaxDigits        = 8,
                    MaxTries         = 3,
                    TimeoutMs        = 4000,
                    TerminatorDigits = "#",
                    PromptAudioFile  =
                        "ivr/ivr-please_enter_pin_followed_by_pound.wav",
                    BadInputAudioFile = "ivr/ivr-that_was_an_invalid_entry.wav",
                    DigitTimeoutMs    = 2000,
                });

                ColorConsole.WriteLine("Got digits: ".Blue(), playGetDigitsResult.Digits);

                if (playGetDigitsResult.Success)
                {
                    await client.Play(uuid, "ivr/ivr-you_entered.wav");

                    await
                    client.Say(
                        uuid,
                        new SayOptions()
                    {
                        Text   = playGetDigitsResult.Digits,
                        Type   = SayType.Number,
                        Method = SayMethod.Iterated
                    });

                    await
                    client.Play(
                        uuid, "ivr/ivr-you_may_exit_by_hanging_up.wav", new PlayOptions()
                    {
                        Loops = 3
                    });

                    await client.Hangup(uuid, HangupCause.CallRejected);
                }
            }
        }