示例#1
0
        private static async Task <OriginateResult> InternalOriginate(EventSocket socket, string endpoint, string destination, OriginateOptions options = null)
        {
            if (options == null)
            {
                options = new OriginateOptions();
            }

            // if no UUID provided, we'll set one now and use that to filter for the correct channel events
            // this way, one inbound socket can originate many calls and we can complete the correct
            // TaskCompletionSource for each originated call.
            if (string.IsNullOrEmpty(options.UUID))
            {
                options.UUID = Guid.NewGuid().ToString();
            }

            await socket.SubscribeEvents(EventName.ChannelAnswer, EventName.ChannelHangup, EventName.ChannelProgress).ConfigureAwait(false);

            var originateString = string.Format("{0}{1} {2}", options, endpoint, destination);

            return
                (await
                 socket.BackgroundJob("originate", originateString)
                 .ToObservable()
                 .Merge(
                     socket.ChannelEvents.FirstAsync(
                         x =>
                         x.UUID == options.UUID &&
                         (x.EventName == EventName.ChannelAnswer || x.EventName == EventName.ChannelHangup ||
                          (options.ReturnRingReady && x.EventName == EventName.ChannelProgress))).Cast <BasicMessage>())
                 .FirstAsync(x => (x is BackgroundJobResult && !((BackgroundJobResult)x).Success) || x is ChannelEvent)
                 .Select(OriginateResult.FromBackgroundJobResultOrChannelEvent)        // pattern matching, my kingdom for pattern matching
                 .ToTask()
                 .ConfigureAwait(false));
        }
示例#2
0
        protected Channel(EventMessage eventMessage, EventSocket eventSocket) : base(eventMessage, eventSocket)
        {
            eventSocket.SubscribeEvents(EventName.ChannelCreate).Wait();

            Disposables.Add(
                eventSocket.Events.Where(x => x.UUID == UUID && x.EventName == EventName.ChannelBridge).Subscribe(
                    x =>
            {
                Log.Trace(() => "Channel [{0}] Bridged to [{1}]".Fmt(UUID, x.GetHeader(HeaderNames.OtherLegUniqueId)));

                if (Bridge.Channel != null && x.GetHeader(HeaderNames.OtherLegUniqueId) != Bridge.Channel.UUID)
                {
                    //possibly changed bridge partner as part of att_xfer
                    Log.Warn(() => "Channel [{0}] was Bridged to [{1}] but now changed to [{2}]".Fmt(UUID, Bridge.Channel.UUID, x.UUID));

                    Bridge.Channel.Dispose();
                    Bridge = new BridgeStatus(true, "TRANSFERRED", new BridgedChannel(x, eventSocket));
                }
            }));

            Disposables.Add(
                eventSocket.Events.Where(x => x.UUID == UUID && x.EventName == EventName.ChannelUnbridge).Subscribe(
                    x => Log.Trace(() => "Channel [{0}] Unbridged from [{1}] {2}".Fmt(UUID, Bridge.Channel.UUID, x.GetVariable("bridge_hangup_cause")))));

            Disposables.Add(
                eventSocket.Events.Where(x => x.EventName == EventName.ChannelBridge &&
                                         x.UUID != UUID &&
                                         x.GetHeader(HeaderNames.OtherLegUniqueId) == UUID &&
                                         (Bridge.Channel != null && x.UUID != Bridge.Channel.UUID))
                .Subscribe(x =>
            {
                //there is another channel out there that has bridged to us but we didn't get the CHANNEL_BRIDGE event on this channel
                //possibly an attended transfer. We'll swap our bridge partner so we can get its events

                Log.Warn(() => "Channel [{0}] was Bridged to [{1}] but now changed to [{2}]".Fmt(UUID, Bridge.Channel.UUID, x.UUID));

                Bridge.Channel.Dispose();
                Bridge = new BridgeStatus(true, "TRANSFERRED", new BridgedChannel(x, eventSocket));
            }));

            if (this.eventSocket is OutboundSocket)
            {
                Disposables.Add(
                    eventSocket.Events.Where(x => x.UUID == UUID && x.EventName == EventName.ChannelHangup)
                    .Subscribe(async e =>
                {
                    if (ExitOnHangup)
                    {
                        await eventSocket.Exit();
                        Log.Info(() => "Channel [{0}] exited".Fmt(UUID));
                    }
                }));
            }

            //populate empty bridge status
            Bridge       = new BridgeStatus(false, null);
            ExitOnHangup = true;
        }
示例#3
0
 public Task StartDetectingInbandDtmf()
 {
     return(RunIfAnswered(
                async() =>
     {
         await eventSocket.SubscribeEvents(EventName.Dtmf).ConfigureAwait(false);
         await eventSocket.StartDtmf(UUID).ConfigureAwait(false);
     }));
 }
示例#4
0
        public async Task StartDetectingInbandDtmf()
        {
            if (!IsAnswered)
            {
                return;
            }

            await eventSocket.SubscribeEvents(EventName.Dtmf);

            await eventSocket.StartDtmf(UUID);
        }
示例#5
0
        private static async Task <OriginateResult> InternalOriginate(EventSocket socket, string endpoint, string destination, OriginateOptions options = null)
        {
            if (options == null)
            {
                options = new OriginateOptions();
            }
            var originateString = $"{options}{endpoint} {destination}";

            await socket.SubscribeEvents(EventName.BackgroundJob).ConfigureAwait(false);

            return
                (await
                 socket.BackgroundJob("originate", originateString)
                 .ToObservable()
                 .Select(OriginateResult.FromBackgroundJobResultOrChannelEvent)
                 .ToTask()
                 .ConfigureAwait(false));
        }
示例#6
0
        protected Channel(EventMessage eventMessage, EventSocket eventSocket) : base(eventMessage, eventSocket)
        {
            //populate empty bridge status
            Bridge       = new BridgeStatus(false, null);
            ExitOnHangup = true;

            Task.WhenAll(
                new[]
            {
                eventSocket.SubscribeEvents(),                         //subscribe to minimum events
                eventSocket.Filter(HeaderNames.UniqueId, UUID),        //filter for our unique id (in case using full socket mode)
                eventSocket.Filter(HeaderNames.OtherLegUniqueId, UUID) //filter for channels bridging to our unique id
            }).ContinueWith(
                t =>
            {
                if (t.IsFaulted && t.Exception != null)
                {
                    Log.ErrorException("Channel [{0}] - failed to configure outbound socket for Channel usage".Fmt(UUID), t.Exception.InnerException);
                    return;
                }

                this.InitializeSubscriptions();
            });
        }