Esempio n. 1
0
 /// <summary>
 /// Register a callback to be invoked when the given Channel UUID hangs up.
 /// </summary>
 /// <param name="uuid">The Channel UUID.</param>
 /// <param name="action">A Callback to be invoked on hangup.</param>
 public void OnHangup(string uuid, Action <EventMessage> action)
 {
     ChannelEvents.Where(x => x.UUID == uuid && x.EventName == EventName.ChannelHangup).Take(1).Subscribe(action);
 }
Esempio n. 2
0
        /// <summary>
        /// Asynchronously executes a dialplan application on the given channel.
        /// </summary>
        /// <remarks>
        /// See https://freeswitch.org/confluence/display/FREESWITCH/mod_dptools
        /// </remarks>
        /// <param name="uuid">The channel UUID.</param>
        /// <param name="application">The dialplan application to execute.</param>
        /// <param name="applicationArguments">(Optional) arguments to pass to the application.</param>
        /// <param name="eventLock">(Default: false) Whether to block the socket until the application completes before processing further.
        ///  (see https://wiki.freeswitch.org/wiki/Event_Socket_Outbound#Q:_Ordering_and_async_keyword )</param>
        /// <param name="async">(Default: false) Whether to return control from the application immediately.
        /// (see https://wiki.freeswitch.org/wiki/Event_Socket_Outbound#Q:_Should_I_use_sync_mode_or_async_mode.3F)
        /// </param>
        /// <param name="loops">(Optional) How many times to repeat the application.</param>
        /// <returns>
        /// A Task of <seealso cref="EventMessage"/> that wraps the ChannelExecuteComplete event if the application completes successfully.
        /// The Task result will be null if the application did not execute, for example, the socket disconnected or the channel was hung up.
        /// </returns>
        public Task <ChannelEvent> ExecuteApplication(
            string uuid, string application, string applicationArguments = null, bool eventLock = false, bool async = false, int loops = 1)
        {
            if (uuid == null)
            {
                throw new ArgumentNullException("uuid");
            }

            if (application == null)
            {
                throw new ArgumentNullException("application");
            }

            //lists.freeswitch.org/pipermail/freeswitch-users/2013-May/095329.html
            var applicationUUID = Guid.NewGuid().ToString();

            var sb = StringBuilderPool.Allocate();

            sb.AppendFormat("sendmsg {0}\nEvent-UUID: {1}\ncall-command: execute\nexecute-app-name: {2}\n", uuid, applicationUUID, application);

            if (eventLock)
            {
                sb.Append("event-lock: true\n");
            }

            if (loops > 1)
            {
                sb.Append("loops: " + loops + "\n");
            }

            if (async)
            {
                sb.Append("async: true\n");
            }

            if (applicationArguments != null)
            {
                sb.AppendFormat("content-type: text/plain\ncontent-length: {0}\n\n{1}\n", applicationArguments.Length, applicationArguments);
            }

            var tcs           = new TaskCompletionSource <ChannelEvent>();
            var subscriptions = new CompositeDisposable();

            if (cts.Token.CanBeCanceled)
            {
                subscriptions.Add(cts.Token.Register(() => tcs.TrySetCanceled()));
            }

            subscriptions.Add(
                ChannelEvents.Where(
                    x => x.EventName == EventName.ChannelExecuteComplete && x.Headers["Application-UUID"] == applicationUUID)
                .Take(1)
                .Subscribe(
                    executeCompleteEvent =>
            {
                if (executeCompleteEvent != null)
                {
                    Console.WriteLine("{0} ChannelExecuteComplete [{1} {2} {3}]".Fmt(
                                          executeCompleteEvent.UUID,
                                          executeCompleteEvent.AnswerState,
                                          executeCompleteEvent.Headers[HeaderNames.Application],
                                          executeCompleteEvent.Headers[HeaderNames.ApplicationResponse]));
                }
                else
                {
                    Console.WriteLine("No ChannelExecuteComplete event received for {0}".Fmt(application));
                }

                tcs.TrySetResult(executeCompleteEvent);
            },
                    ex => tcs.TrySetException(ex),
                    subscriptions.Dispose));

            SubscribeEvents(EventName.ChannelExecuteComplete).ContinueWith(t =>
            {
                if (t.IsCompleted)
                {
                    SendCommand(StringBuilderPool.ReturnAndFree(sb))
                    .Then(reply =>
                    {
                        if (!reply.Success)
                        {
                            tcs.TrySetResult(null);
                        }
                    })
                    .ContinueOnFaultedOrCancelled(tcs, subscriptions.Dispose);
                }
                else
                {
                    tcs.TrySetException(t.Exception);
                }
            });

            return(tcs.Task);
        }