示例#1
0
        /// <summary>
        /// Plays the given file to the specified channel.
        /// </summary>
        /// <param name="eventSocket">The EventSocket instance.</param>
        /// <param name="uuid">The Channel UUID.</param>
        /// <param name="file">The Path to the file to be played. Note: use forward slashes for path separators.</param>
        /// <param name="options">Options to customize playback.</param>
        /// <returns>A PlayResult.</returns>
        /// <exception cref="FileNotFoundException">Throws FileNotFoundException if FreeSwitch is unable to play the file.</exception>//todo: should it?
        public static async Task <PlayResult> Play(this EventSocket eventSocket, string uuid, string file, PlayOptions options = null)
        {
            // todo: implement options for playback eg a-leg, b-leg, both, using uuid_displace
            if (options == null)
            {
                options = new PlayOptions();
            }

            try
            {
                // todo: what if applicationresult is null (hang up occurs before the application completes)
                var result =
                    new PlayResult(
                        await
                        eventSocket.ExecuteApplication(uuid, "playback", file, loops: options.Loops)
                        .ConfigureAwait(false));

                if (!result.Success)
                {
                    LogFailedApplicationResult(eventSocket, result);
                }

                return(result);
            }
            catch (TaskCanceledException ex)
            {
                return(new PlayResult(null));
            }
        }
示例#2
0
        public async Task PlayFile(string file, Leg leg = Leg.ALeg, bool mix = false, string terminator = null)
        {
            if (!IsAnswered)
            {
                return;
            }

            if (terminator != null)
            {
                await SetChannelVariable("playback_terminators", terminator);
            }

            if (leg == Leg.ALeg) //!this.IsBridged)
            {
                await eventSocket.Play(UUID, file, new PlayOptions());

                return;
            }

            // uuid displace only works on one leg
            switch (leg)
            {
            case Leg.Both:
                await
                Task.WhenAll(
                    eventSocket.ExecuteApplication(UUID, "displace_session", "{0} {1}{2}".Fmt(file, mix ? "m" : string.Empty, "w"), false, false),
                    eventSocket.ExecuteApplication(UUID, "displace_session", "{0} {1}{2}".Fmt(file, mix ? "m" : string.Empty, "r"), false, false));

                break;

            case Leg.ALeg:
                await eventSocket.ExecuteApplication(UUID, "displace_session", "{0} {1}{2}".Fmt(file, mix ? "m" : string.Empty, "w"), false, false);

                break;

            case Leg.BLeg:
                await eventSocket.ExecuteApplication(UUID, "displace_session", "{0} {1}{2}".Fmt(file, mix ? "m" : string.Empty, "r"), false, false);

                break;

            default:
                throw new NotSupportedException("Leg {0} is not supported".Fmt(leg));
            }
        }
示例#3
0
        public static async Task <ReadResult> Read(this EventSocket eventSocket, string uuid, ReadOptions options)
        {
            try
            {
                // todo: what if applicationresult is null (hang up occurs before the application completes)
                var result = new ReadResult(
                    await eventSocket.ExecuteApplication(uuid, "read", options.ToString()).ConfigureAwait(false),
                    options.ChannelVariableName);

                if (!result.Success)
                {
                    LogFailedApplicationResult(eventSocket, result);
                }

                return(result);
            }
            catch (TaskCanceledException ex)
            {
                return(new ReadResult(null, null));
            }
        }
示例#4
0
        public static async Task <PlayGetDigitsResult> PlayGetDigits(this EventSocket eventSocket, string uuid, PlayGetDigitsOptions options)
        {
            try
            {
                // todo: what if applicationresult is null (hang up occurs before the application completes)
                var result =
                    new PlayGetDigitsResult(
                        await eventSocket.ExecuteApplication(uuid, "play_and_get_digits", options.ToString()).ConfigureAwait(false),
                        options.ChannelVariableName);

                if (!result.Success)
                {
                    LogFailedApplicationResult(result);
                }

                return(result);
            }
            catch (TaskCanceledException)
            {
                return(new PlayGetDigitsResult(null, null));
            }
        }
示例#5
0
        /// <summary>
        /// Performs an attended transfer. If succeded, it will replace the Bridged Channel of the other Leg.
        /// </summary>
        /// <remarks>
        /// See https://freeswitch.org/confluence/display/FREESWITCH/Attended+Transfer
        /// </remarks>
        /// <param name="endpoint">The endpoint to transfer to eg. user/1000, sofia/[email protected] etc</param>
        public Task <AttendedTransferResult> AttendedTransfer(string endpoint)
        {
            try
            {
                var tcs           = new TaskCompletionSource <AttendedTransferResult>();
                var subscriptions = new CompositeDisposable();

                var aLegUUID = lastEvent.Headers[HeaderNames.OtherLegUniqueId];
                var bLegUUID = UUID;

                var events = eventSocket.ChannelEvents;

                Log.Debug(() => "Att XFer Starting A-Leg [{0}] B-Leg [{1}]".Fmt(aLegUUID, bLegUUID));

                var aLegHangup = events.Where(x => x.EventName == EventName.ChannelHangup && x.UUID == aLegUUID)
                                 .Do(x => Log.Debug(() => "Att XFer Hangup Detected on A-Leg [{0}]".Fmt(x.UUID)));

                var bLegHangup = events.Where(x => x.EventName == EventName.ChannelHangup && x.UUID == bLegUUID)
                                 .Do(x => Log.Debug(() => "Att XFer Hangup Detected on B-Leg [{0}]".Fmt(x.UUID)));

                var cLegHangup = events.Where(x => x.EventName == EventName.ChannelHangup && x.UUID != bLegUUID && x.UUID != aLegUUID)
                                 .Do(x => Log.Debug(() => "Att XFer Hangup Detected on C-Leg[{0}]".Fmt(x.UUID)));

                var cLegAnswer =
                    events.Where(x => x.EventName == EventName.ChannelAnswer && x.UUID != bLegUUID && x.UUID != aLegUUID)
                    .Do(x => Log.Debug(() => "Att XFer Answer Detected on C-Leg [{0}]".Fmt(x.UUID)));

                var aLegBridge =
                    events.Where(x => x.EventName == EventName.ChannelBridge && x.UUID == aLegUUID)
                    .Do(x => Log.Debug(() => "Att XFer Bridge Detected on A-Leg [{0}]".Fmt(x.UUID)));

                var cLegBridge =
                    events.Where(x => x.EventName == EventName.ChannelBridge && x.UUID != bLegUUID && x.UUID != aLegUUID)
                    .Do(x => Log.Debug(() => "Att XFer Bridge Detected on C-Leg [{0}]".Fmt(x.UUID)));


                var channelExecuteComplete =
                    events.Where(
                        x =>
                        x.EventName == EventName.ChannelExecuteComplete &&
                        x.UUID == bLegUUID &&
                        x.GetHeader(HeaderNames.Application) == "att_xfer");


                var cAnsweredThenHungUp =
                    cLegAnswer.And(cLegHangup)
                    .And(channelExecuteComplete.Where(
                             x =>
                             x.GetVariable("att_xfer_result") == "success" &&
                             x.GetVariable("last_bridge_hangup_cause") == "NORMAL_CLEARING" &&
                             x.GetVariable("originate_disposition") == "SUCCESS"));

                var cAnsweredThenBPressedStarOrHungUp =
                    cLegAnswer.And(bLegHangup)
                    .And(cLegBridge.Where(x => x.OtherLegUUID == aLegUUID));

                subscriptions.Add(channelExecuteComplete.Where(x => x.GetVariable("originate_disposition") != "SUCCESS")
                                  .Subscribe(
                                      x =>
                {
                    Log.Debug(() => "Att Xfer Not Answered");
                    tcs.TrySetResult(AttendedTransferResult.Failed(x.GetVariable("originate_disposition").HeaderToEnum <HangupCause>()));
                }));

                subscriptions.Add(Observable.When(cAnsweredThenHungUp.Then((answer, hangup, execComplete) => new { answer, hangup, execComplete }))
                                  .Subscribe(
                                      x =>
                {
                    Log.Debug(() => "Att Xfer Rejected after C Hungup");
                    tcs.TrySetResult(AttendedTransferResult.Failed(FreeSwitch.HangupCause.NormalClearing));
                }));

                subscriptions.Add(channelExecuteComplete.Where(x => !string.IsNullOrEmpty(x.GetVariable("xfer_uuids")))
                                  .Subscribe(x => {
                    Log.Debug(() => "Att Xfer Success (threeway)");
                    tcs.TrySetResult(AttendedTransferResult.Success(AttendedTransferResultStatus.Threeway));
                }));

                subscriptions.Add(Observable.When(cAnsweredThenBPressedStarOrHungUp.Then((answer, hangup, bridge) => new { answer, hangup, bridge }))
                                  .Subscribe(
                                      x =>
                {
                    Log.Debug(() => "Att Xfer Succeeded after B pressed *");
                    tcs.TrySetResult(AttendedTransferResult.Success());
                }));

                subscriptions.Add(Observable.When(bLegHangup.And(cLegAnswer).And(aLegBridge.Where(x => x.OtherLegUUID != bLegUUID)).Then((hangup, answer, bridge) => new { answer, hangup, bridge }))
                                  .Subscribe(
                                      x =>
                {
                    Log.Debug(() => "Att Xfer Succeeded after B hung up and C answered");
                    tcs.TrySetResult(AttendedTransferResult.Success());
                }));

                subscriptions.Add(aLegHangup.Subscribe(
                                      x =>
                {
                    Log.Debug(() => "Att Xfer Failed after A-Leg Hung Up");
                    tcs.TrySetResult(AttendedTransferResult.Hangup(x));
                }));

                eventSocket.ExecuteApplication(UUID, "att_xfer", endpoint, false, true)
                .ContinueOnFaultedOrCancelled(tcs, subscriptions.Dispose);

                return(tcs.Task.Then(() => subscriptions.Dispose()));
            }
            catch (TaskCanceledException)
            {
                return(Task.FromResult(AttendedTransferResult.Failed(FreeSwitch.HangupCause.None)));
            }
        }
示例#6
0
 public static Task <EventMessage> Stoptmf(this EventSocket eventSocket, string uuid)
 {
     return(eventSocket.ExecuteApplication(uuid, "spandsp_stop_dtmf"));
 }
示例#7
0
 public static Task <EventMessage> Say(this EventSocket eventSocket, string uuid, SayOptions options)
 {
     return(eventSocket.ExecuteApplication(uuid, "say", options.ToString()));
 }
示例#8
0
 public static Task <ChannelEvent> StopDtmf(this EventSocket eventSocket, string uuid)
 {
     return(eventSocket.ExecuteApplication(uuid, "spandsp_stop_dtmf"));
 }