Skip to content

Commit

Permalink
Merge branch 'refs/heads/develop' into feature/asterisk_join_api
Browse files Browse the repository at this point in the history
Conflicts:
	CHANGELOG.md
	lib/punchblock/translator/asterisk.rb
  • Loading branch information
benlangfeld committed Mar 5, 2012
2 parents 0921302 + df7032d commit 0bfd229
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,5 +1,6 @@
# develop
* Feature: Asterisk calls now support the Join API (joining only)
* Bugfix: The Asterisk translator now ignores calls to 'h' or of type 'Kill'

# v0.9.2 - 2012-02-18
* Feature: Asterisk calls receiving media commands are implicitly answered
Expand Down
7 changes: 6 additions & 1 deletion lib/punchblock/translator/asterisk.rb
Expand Up @@ -145,8 +145,13 @@ def send_ami_action(name, headers = {}, &block)
private

def handle_async_agi_start_event(event)
env = Call.parse_environment event['Env']

return pb_logger.warn "Ignoring AsyncAGI Start event because it is for an 'h' extension" if env[:agi_extension] == 'h'
return pb_logger.warn "Ignoring AsyncAGI Start event because it is for an 'Kill' type" if env[:agi_type] == 'Kill'

pb_logger.trace "Handling AsyncAGI Start event by creating a new call"
call = Call.new event['Channel'], current_actor, event['Env']
call = Call.new event['Channel'], current_actor, env
register_call call
call.send_offer!
end
Expand Down
28 changes: 15 additions & 13 deletions lib/punchblock/translator/asterisk/call.rb
Expand Up @@ -18,9 +18,22 @@ class Call
HANGUP_CAUSE_TO_END_REASON[22] = :reject
HANGUP_CAUSE_TO_END_REASON[102] = :timeout

def initialize(channel, translator, agi_env = '')
class << self
def parse_environment(agi_env)
agi_env_as_array(agi_env).inject({}) do |accumulator, element|
accumulator[element[0].to_sym] = element[1] || ''
accumulator
end
end

def agi_env_as_array(agi_env)
URI.unescape(agi_env).encode.split("\n").map { |p| p.split ': ' }
end
end

def initialize(channel, translator, agi_env = nil)
@channel, @translator = channel, translator
@agi_env = parse_environment agi_env
@agi_env = agi_env || {}
@id, @components = UUIDTools::UUID.random_create.to_s, {}
@answered = false
@pending_joins = {}
Expand Down Expand Up @@ -231,17 +244,6 @@ def sip_headers
accumulator
end
end

def parse_environment(agi_env)
agi_env_as_array(agi_env).inject({}) do |accumulator, element|
accumulator[element[0].to_sym] = element[1] || ''
accumulator
end
end

def agi_env_as_array(agi_env)
URI.unescape(agi_env).encode.split("\n").map { |p| p.split ': ' }
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion punchblock.gemspec
Expand Up @@ -28,7 +28,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency %q<state_machine>, [">= 1.0.1"]
s.add_runtime_dependency %q<future-resource>, [">= 0.0.2"]
s.add_runtime_dependency %q<has-guarded-handlers>, [">= 0.1.0"]
s.add_runtime_dependency %q<celluloid>, [">= 0.6.0"]
s.add_runtime_dependency %q<celluloid>, [">= 0.9.0"]
s.add_runtime_dependency %q<ruby_ami>, [">= 0.1.3"]
s.add_runtime_dependency %q<ruby_speech>, [">= 0.5.1"]

Expand Down
2 changes: 0 additions & 2 deletions spec/punchblock/connection/asterisk_spec.rb
Expand Up @@ -24,8 +24,6 @@ module Connection

its(:ami_client) { should be_a RubyAMI::Client }

after { connection.translator.terminate }

it 'should set the connection on the translator' do
subject.translator.connection.should be subject
end
Expand Down
3 changes: 1 addition & 2 deletions spec/punchblock/translator/asterisk/call_spec.rb
Expand Up @@ -6,7 +6,6 @@ class Asterisk
describe Call do
let(:channel) { 'SIP/foo' }
let(:translator) { stub_everything 'Translator::Asterisk' }
let(:env) { "agi_request%3A%20async%0Aagi_channel%3A%20SIP%2F1234-00000000%0Aagi_language%3A%20en%0Aagi_type%3A%20SIP%0Aagi_uniqueid%3A%201320835995.0%0Aagi_version%3A%201.8.4.1%0Aagi_callerid%3A%205678%0Aagi_calleridname%3A%20Jane%20Smith%0Aagi_callingpres%3A%200%0Aagi_callingani2%3A%200%0Aagi_callington%3A%200%0Aagi_callingtns%3A%200%0Aagi_dnid%3A%201000%0Aagi_rdnis%3A%20unknown%0Aagi_context%3A%20default%0Aagi_extension%3A%201000%0Aagi_priority%3A%201%0Aagi_enhanced%3A%200.0%0Aagi_accountcode%3A%20%0Aagi_threadid%3A%204366221312%0A%0A" }
let(:agi_env) do
{
:agi_request => 'async',
Expand Down Expand Up @@ -57,7 +56,7 @@ class Asterisk
}
end

subject { Call.new channel, translator, env }
subject { Call.new channel, translator, agi_env }

its(:id) { should be_a String }
its(:channel) { should == channel }
Expand Down
63 changes: 62 additions & 1 deletion spec/punchblock/translator/asterisk_spec.rb
Expand Up @@ -294,7 +294,28 @@ module Translator
call_actor = subject.call_for_channel('SIP/1234-00000000')
call_actor.wrapped_object.should be_a Asterisk::Call
call_actor.agi_env.should be_a Hash
call_actor.agi_env[:agi_request].should == 'async'
call_actor.agi_env.should == {
:agi_request => 'async',
:agi_channel => 'SIP/1234-00000000',
:agi_language => 'en',
:agi_type => 'SIP',
:agi_uniqueid => '1320835995.0',
:agi_version => '1.8.4.1',
:agi_callerid => '5678',
:agi_calleridname => 'Jane Smith',
:agi_callingpres => '0',
:agi_callingani2 => '0',
:agi_callington => '0',
:agi_callingtns => '0',
:agi_dnid => '1000',
:agi_rdnis => 'unknown',
:agi_context => 'default',
:agi_extension => '1000',
:agi_priority => '1',
:agi_enhanced => '0.0',
:agi_accountcode => '',
:agi_threadid => '4366221312'
}
end

it 'should instruct the call to send an offer' do
Expand All @@ -316,6 +337,46 @@ module Translator
subject.handle_ami_event ami_event
end
end

context "for a 'h' extension" do
let :ami_event do
RubyAMI::Event.new('AsyncAGI').tap do |e|
e['SubEvent'] = "Start"
e['Channel'] = "SIP/1234-00000000"
e['Env'] = "agi_extension%3A%20h%0A%0A"
end
end

it "should not create a new call" do
Asterisk::Call.expects(:new).never
subject.handle_ami_event ami_event
end

it 'should not be able to look up the call by channel ID' do
subject.handle_ami_event ami_event
subject.call_for_channel('SIP/1234-00000000').should be nil
end
end

context "for a 'Kill' type" do
let :ami_event do
RubyAMI::Event.new('AsyncAGI').tap do |e|
e['SubEvent'] = "Start"
e['Channel'] = "SIP/1234-00000000"
e['Env'] = "agi_type%3A%20Kill%0A%0A"
end
end

it "should not create a new call" do
Asterisk::Call.expects(:new).never
subject.handle_ami_event ami_event
end

it 'should not be able to look up the call by channel ID' do
subject.handle_ami_event ami_event
subject.call_for_channel('SIP/1234-00000000').should be nil
end
end
end

describe 'with a VarSet event including a punchblock_call_id' do
Expand Down
6 changes: 4 additions & 2 deletions spec/spec_helper.rb
@@ -1,5 +1,3 @@
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
$LOAD_PATH.unshift File.dirname(__FILE__)
require 'punchblock'
require 'mocha'
require 'countdownlatch'
Expand All @@ -15,6 +13,10 @@
config.before :suite do |variable|
Punchblock.logger = Logger.new(STDOUT)
end

config.after :each do
Object.const_defined?(:Celluloid) && Celluloid.shutdown
end
end

def parse_stanza(xml)
Expand Down

0 comments on commit 0bfd229

Please sign in to comment.