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; }
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); } }
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); } }
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(); }); }
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); }
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); }
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)); }