Ejemplo n.º 1
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;
        }
Ejemplo n.º 2
0
        public async Task BridgeTo(Channel other)
        {
            if (IsBridged)
            {
                throw new InvalidOperationException("Channel {0} is already bridged to {1}".Fmt(UUID, Bridge.Channel.UUID));
            }

            if (!(IsAnswered || IsPreAnswered) && !(other.IsAnswered || other.IsPreAnswered))
            {
                throw new InvalidOperationException("At least one channel must be Answered to bridge them");
            }

            var result = await eventSocket.SendApi("uuid_bridge {0} {1}".Fmt(UUID, other.UUID)).ConfigureAwait(false);

            if (result.Success)
            {
                Bridge = new BridgeStatus(result.Success, result.BodyText, new BridgedChannel(other.lastEvent, eventSocket));
            }
            else
            {
                Bridge = new BridgeStatus(result.Success, result.ErrorMessage);
            }
        }
Ejemplo n.º 3
0
        public async Task BridgeTo(Channel other)
        {
            if (IsBridged)
            {
                throw new InvalidOperationException("Channel {0} is already bridged to {1}".Fmt(UUID, Bridge.Channel.UUID));
            }

            if (Answered != AnswerState.Answered && other.Answered != AnswerState.Answered)
            {
                throw new InvalidOperationException("At least one channel must be Answered to bridge them");
            }

            var result = await eventSocket.SendApi("uuid_bridge {0} {1}".Fmt(UUID, other.UUID));

            if (result.Success)
            {
                Bridge = new BridgeStatus(result.Success, result.BodyText, new BridgedChannel(other.lastEvent, eventSocket));
            }
            else
            {
                Bridge = new BridgeStatus(result.Success, result.ErrorMessage);
            }
        }
Ejemplo n.º 4
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();
                            });
        }
Ejemplo n.º 5
0
        public async Task BridgeTo(string destination, BridgeOptions options, Action <EventMessage> onProgress = null)
        {
            if (!IsAnswered)
            {
                return;
            }

            Log.Debug(() => "Channel {0} is attempting a bridge to {1}".Fmt(UUID, destination));

            if (string.IsNullOrEmpty(options.UUID))
            {
                options.UUID = Guid.NewGuid().ToString();
            }

            var subscriptions = new CompositeDisposable();

            subscriptions.Add(
                eventSocket.Events.Where(x => x.UUID == options.UUID)
                .Take(1)
                .Subscribe(x => Bridge = new BridgeStatus(false, "In Progress", new BridgedChannel(x, eventSocket))));

            if (onProgress != null)
            {
                subscriptions.Add(
                    eventSocket.Events.Where(x => x.UUID == options.UUID && x.EventName == EventName.ChannelProgress)
                    .Take(1)
                    .Subscribe(onProgress));
            }

            var result = await eventSocket.Bridge(UUID, destination, options);

            Log.Debug(() => "Channel {0} bridge complete {1} {2}".Fmt(UUID, result.Success, result.ResponseText));
            subscriptions.Dispose();

            Bridge = new BridgeStatus(result.Success, result.ResponseText, Bridge.Channel);
        }
Ejemplo n.º 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();
            });
        }
Ejemplo n.º 7
0
        public async Task BridgeTo(string destination, BridgeOptions options, Action<EventMessage> onProgress = null)
        {
            if (!IsAnswered && !IsPreAnswered)
            {
                return;
            }

            Log.Debug(() => "Channel {0} is attempting a bridge to {1}".Fmt(UUID, destination));

            if (string.IsNullOrEmpty(options.UUID))
            {
                options.UUID = Guid.NewGuid().ToString();
            }

            var subscriptions = new CompositeDisposable();

            subscriptions.Add(
                eventSocket.Events.Where(x => x.UUID == options.UUID)
                    .Take(1)
                    .Subscribe(x => Bridge = new BridgeStatus(false, "In Progress", new BridgedChannel(x, eventSocket))));

            if (onProgress != null)
            {
                subscriptions.Add(
                    eventSocket.Events.Where(x => x.UUID == options.UUID && x.EventName == EventName.ChannelProgress)
                        .Take(1)
                        .Subscribe(onProgress));
            }

            var result = await eventSocket.Bridge(UUID, destination, options).ConfigureAwait(false);

            Log.Debug(() => "Channel {0} bridge complete {1} {2}".Fmt(UUID, result.Success, result.ResponseText));
            subscriptions.Dispose();

            Bridge = new BridgeStatus(result.Success, result.ResponseText, Bridge.Channel);
        }
Ejemplo n.º 8
0
        private void InitializeSubscriptions()
        {
            if (initialized.EnsureCalledOnce())
            {
                Log.Warn(() => "Channel already initialized");
                return;
            }

            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(
                                   e =>
                                   {
                                       if (ExitOnHangup)
                                       {
                                           Log.Info(() => "Channel [{0}] exiting".Fmt(UUID));
                                           eventSocket.Exit(); //don't care about the result, no need to wait
                                       }
                                   }));
            }

            Log.Trace(() => "Channel [{0}] subscriptions initialized".Fmt(UUID));
        }
Ejemplo n.º 9
0
        private void InitializeSubscriptions()
        {
            if (initialized.EnsureCalledOnce())
            {
                Log.Warn(() => "Channel already initialized");
                return;
            }

            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(
                        e =>
                {
                    if (ExitOnHangup)
                    {
                        Log.Info(() => "Channel [{0}] exiting".Fmt(UUID));
                        eventSocket.Exit();                    //don't care about the result, no need to wait
                    }
                }));
            }

            Log.Trace(() => "Channel [{0}] subscriptions initialized".Fmt(UUID));
        }