lib/adhearsion/call.rb in adhearsion-2.5.4 vs lib/adhearsion/call.rb in adhearsion-2.6.0
- old
+ new
@@ -1,10 +1,12 @@
# encoding: utf-8
require 'has_guarded_handlers'
require 'thread'
require 'active_support/hash_with_indifferent_access'
+require 'active_support/core_ext/hash/indifferent_access'
+require 'adhearsion'
module Adhearsion
##
# Encapsulates call-related data and behavior.
#
@@ -46,13 +48,16 @@
attr_reader :start_time
# @return [Time] the time at which the call began. For inbound calls this is the time at which the call was offered to Adhearsion. For outbound calls it is the time at which the remote party answered.
attr_reader :end_time
- # @return [true, false] wether or not the call should be automatically hung up after executing its controller
+ # @return [true, false] whether or not the call should be automatically hung up after executing its controller
attr_accessor :auto_hangup
+ # @return [Integer] the number of seconds after the call is hung up that the controller will remain active
+ attr_accessor :after_hangup_lifetime
+
delegate :[], :[]=, :to => :variables
# @return [String] the value of the To header from the signaling protocol
delegate :to, to: :offer, allow_nil: true
@@ -80,10 +85,11 @@
@end_code = nil
@end_blocker = Celluloid::Condition.new
@peers = {}
@duration = nil
@auto_hangup = true
+ @after_hangup_lifetime = nil
self << offer if offer
end
#
@@ -228,19 +234,19 @@
@peers.delete target
signal :unjoined, target
end
on_end do |event|
- logger.info "Call ended due to #{event.reason}"
+ logger.info "Call #{from} -> #{to} ended due to #{event.reason}#{" (code #{event.platform_code})" if event.platform_code}"
@end_time = event.timestamp.to_time
@duration = @end_time - @start_time if @start_time
clear_from_active_calls
@end_reason = event.reason
@end_code = event.platform_code
@end_blocker.broadcast event.reason
@commands.terminate
- after(Adhearsion.config.platform.after_hangup_lifetime) { terminate }
+ after(@after_hangup_lifetime || Adhearsion.config.platform.after_hangup_lifetime) { terminate }
end
end
# @return [Float] The call duration until the current time, or until the call was disconnected, whichever is earlier
def duration
@@ -293,26 +299,54 @@
!end_reason
end
def accept(headers = nil)
@accept_command ||= write_and_await_response Punchblock::Command::Accept.new(:headers => headers)
+ rescue Punchblock::ProtocolError => e
+ abort e
end
def answer(headers = nil)
write_and_await_response Punchblock::Command::Answer.new(:headers => headers)
+ rescue Punchblock::ProtocolError => e
+ abort e
end
def reject(reason = :busy, headers = nil)
write_and_await_response Punchblock::Command::Reject.new(:reason => reason, :headers => headers)
Adhearsion::Events.trigger_immediately :call_rejected, call: current_actor, reason: reason
+ rescue Punchblock::ProtocolError => e
+ abort e
end
+ #
+ # Redirect the call to some other target system.
+ #
+ # If the redirect is successful, the call will be released from the
+ # telephony engine and Adhearsion will lose control of the call.
+ #
+ # Note that for the common case, this will result in a SIP 302 or
+ # SIP REFER, which provides the caller with a new URI to dial. As such,
+ # the redirect target cannot be any telephony-engine specific address
+ # (such as sofia/gateway, agent/101, or SIP/mypeer); instead it should be a
+ # fully-qualified external SIP URI that the caller can independently reach.
+ #
+ # @param [String] to the target to redirect to, eg a SIP URI
+ # @param [Hash, optional] headers a set of headers to send along with the redirect instruction
+ def redirect(to, headers = nil)
+ write_and_await_response Punchblock::Command::Redirect.new(to: to, headers: headers)
+ rescue Punchblock::ProtocolError => e
+ abort e
+ end
+
def hangup(headers = nil)
return false unless active?
logger.info "Hanging up"
@end_reason = true
write_and_await_response Punchblock::Command::Hangup.new(:headers => headers)
+ rescue Punchblock::ProtocolError => e
+ abort e
end
# @private
def clear_from_active_calls
Adhearsion.active_calls.remove_inactive_call current_actor
@@ -347,28 +381,34 @@
end
command = Punchblock::Command::Join.new options.merge(join_options_with_target(target))
write_and_await_response command
{command: command, joined_condition: joined_condition, unjoined_condition: unjoined_condition}
+ rescue Punchblock::ProtocolError => e
+ abort e
end
##
# Unjoins this call from another call or a mixer
#
- # @param [Call, String, Hash] target the target to unjoin from. May be a Call object, a call ID (String, Hash) or a mixer name (Hash)
+ # @param [Call, String, Hash, nil] target the target to unjoin from. May be a Call object, a call ID (String, Hash), a mixer name (Hash) or missing to unjoin from every existing join (nil)
# @option target [String] call_uri The call ID to unjoin from
# @option target [String] mixer_name The mixer to unjoin from
#
- def unjoin(target)
+ def unjoin(target = nil)
logger.info "Unjoining from #{target}"
command = Punchblock::Command::Unjoin.new join_options_with_target(target)
write_and_await_response command
+ rescue Punchblock::ProtocolError => e
+ abort e
end
# @private
def join_options_with_target(target)
case target
+ when nil
+ {}
when Call
{ :call_uri => target.uri }
when String
{ :call_uri => self.class.uri(transport, target, domain) }
when Hash
@@ -400,13 +440,17 @@
end
end
def mute
write_and_await_response Punchblock::Command::Mute.new
+ rescue Punchblock::ProtocolError => e
+ abort e
end
def unmute
write_and_await_response Punchblock::Command::Unmute.new
+ rescue Punchblock::ProtocolError => e
+ abort e
end
# @private
def write_and_await_response(command, timeout = 60, fatal = false)
@commands << command