adhearsion 2.6.4 → 3.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +6 -9
- data/CHANGELOG.md +22 -7
- data/Gemfile +2 -0
- data/README.markdown +4 -5
- data/Rakefile +1 -2
- data/adhearsion.gemspec +19 -8
- data/features/cli_create.feature +19 -3
- data/features/step_definitions/cli_steps.rb +0 -11
- data/features/support/env.rb +3 -4
- data/lib/adhearsion.rb +48 -27
- data/lib/adhearsion/call.rb +34 -50
- data/lib/adhearsion/call_controller.rb +6 -12
- data/lib/adhearsion/call_controller/dial.rb +15 -53
- data/lib/adhearsion/call_controller/input.rb +39 -162
- data/lib/adhearsion/call_controller/input/ask_grammar_builder.rb +44 -0
- data/lib/adhearsion/call_controller/input/menu_builder.rb +136 -0
- data/lib/adhearsion/call_controller/input/prompt_builder.rb +78 -0
- data/lib/adhearsion/call_controller/input/result.rb +46 -0
- data/lib/adhearsion/call_controller/output.rb +48 -67
- data/lib/adhearsion/call_controller/output/abstract_player.rb +3 -3
- data/lib/adhearsion/call_controller/output/async_player.rb +3 -3
- data/lib/adhearsion/call_controller/output/player.rb +1 -1
- data/lib/adhearsion/call_controller/record.rb +23 -8
- data/lib/adhearsion/calls.rb +1 -1
- data/lib/adhearsion/cli_commands/ahn_command.rb +2 -65
- data/lib/adhearsion/cli_commands/thor_errors.rb +0 -6
- data/lib/adhearsion/configuration.rb +91 -39
- data/lib/adhearsion/core_ext/blather/stanza.rb +41 -0
- data/lib/adhearsion/core_ext/blather/stanza/presence.rb +13 -0
- data/lib/adhearsion/error.rb +5 -0
- data/lib/adhearsion/event.rb +21 -0
- data/lib/adhearsion/event/active_speaker.rb +11 -0
- data/lib/adhearsion/event/answered.rb +11 -0
- data/lib/adhearsion/event/asterisk.rb +10 -0
- data/lib/adhearsion/event/asterisk/ami.rb +34 -0
- data/lib/adhearsion/event/complete.rb +75 -0
- data/lib/adhearsion/event/dtmf.rb +11 -0
- data/lib/adhearsion/event/end.rb +22 -0
- data/lib/adhearsion/event/input_timers_started.rb +9 -0
- data/lib/adhearsion/event/joined.rb +17 -0
- data/lib/adhearsion/event/offer.rb +14 -0
- data/lib/adhearsion/event/ringing.rb +11 -0
- data/lib/adhearsion/event/started_speaking.rb +13 -0
- data/lib/adhearsion/event/stopped_speaking.rb +13 -0
- data/lib/adhearsion/event/unjoined.rb +17 -0
- data/lib/adhearsion/events.rb +47 -66
- data/lib/adhearsion/foundation.rb +0 -1
- data/lib/adhearsion/foundation/object.rb +0 -5
- data/lib/adhearsion/generators/app/app_generator.rb +4 -1
- data/lib/adhearsion/generators/app/templates/Gemfile.erb +2 -10
- data/lib/adhearsion/generators/app/templates/adhearsion.erb +9 -9
- data/lib/adhearsion/generators/app/templates/config.ru +7 -0
- data/lib/adhearsion/generators/app/templates/en.yml +4 -0
- data/lib/adhearsion/generators/app/templates/events.erb +2 -2
- data/lib/adhearsion/generators/app/templates/hello_world.wav +0 -0
- data/lib/adhearsion/generators/app/templates/simon_game.rb +2 -1
- data/lib/adhearsion/generators/app/templates/simon_game_spec.rb +2 -2
- data/lib/adhearsion/has_headers.rb +34 -0
- data/lib/adhearsion/http_server.rb +37 -0
- data/lib/adhearsion/initializer.rb +19 -153
- data/lib/adhearsion/logging.rb +6 -25
- data/lib/adhearsion/outbound_call.rb +5 -5
- data/lib/adhearsion/plugin.rb +1 -0
- data/lib/adhearsion/protocol_error.rb +26 -0
- data/lib/adhearsion/rayo.rb +30 -0
- data/lib/adhearsion/rayo/client.rb +62 -0
- data/lib/adhearsion/rayo/client/component_registry.rb +33 -0
- data/lib/adhearsion/rayo/command.rb +21 -0
- data/lib/adhearsion/rayo/command/accept.rb +16 -0
- data/lib/adhearsion/rayo/command/answer.rb +16 -0
- data/lib/adhearsion/rayo/command/dial.rb +57 -0
- data/lib/adhearsion/rayo/command/hangup.rb +16 -0
- data/lib/adhearsion/rayo/command/join.rb +43 -0
- data/lib/adhearsion/rayo/command/mute.rb +13 -0
- data/lib/adhearsion/rayo/command/redirect.rb +23 -0
- data/lib/adhearsion/rayo/command/reject.rb +40 -0
- data/lib/adhearsion/rayo/command/unjoin.rb +24 -0
- data/lib/adhearsion/rayo/command/unmute.rb +13 -0
- data/lib/adhearsion/rayo/command_node.rb +47 -0
- data/lib/adhearsion/rayo/component.rb +21 -0
- data/lib/adhearsion/rayo/component/asterisk.rb +13 -0
- data/lib/adhearsion/rayo/component/asterisk/agi.rb +14 -0
- data/lib/adhearsion/rayo/component/asterisk/agi/command.rb +46 -0
- data/lib/adhearsion/rayo/component/asterisk/ami.rb +14 -0
- data/lib/adhearsion/rayo/component/asterisk/ami/action.rb +61 -0
- data/lib/adhearsion/rayo/component/component_node.rb +90 -0
- data/lib/adhearsion/rayo/component/input.rb +186 -0
- data/lib/adhearsion/rayo/component/output.rb +471 -0
- data/lib/adhearsion/rayo/component/prompt.rb +53 -0
- data/lib/adhearsion/rayo/component/receive_fax.rb +26 -0
- data/lib/adhearsion/rayo/component/record.rb +165 -0
- data/lib/adhearsion/rayo/component/send_fax.rb +64 -0
- data/lib/adhearsion/rayo/component/stop.rb +11 -0
- data/lib/adhearsion/rayo/connection.rb +12 -0
- data/lib/adhearsion/rayo/connection/asterisk.rb +74 -0
- data/lib/adhearsion/rayo/connection/connected.rb +22 -0
- data/lib/adhearsion/rayo/connection/generic_connection.rb +22 -0
- data/lib/adhearsion/rayo/connection/xmpp.rb +198 -0
- data/lib/adhearsion/rayo/disconnected_error.rb +22 -0
- data/lib/adhearsion/{punchblock_plugin → rayo}/initializer.rb +19 -19
- data/lib/adhearsion/rayo/rayo_node.rb +127 -0
- data/lib/adhearsion/rayo/ref.rb +57 -0
- data/lib/adhearsion/statistics.rb +1 -1
- data/lib/adhearsion/tasks.rb +1 -2
- data/lib/adhearsion/tasks/configuration.rb +1 -1
- data/lib/adhearsion/tasks/environment.rb +0 -2
- data/lib/adhearsion/tasks/i18n.rb +49 -0
- data/lib/adhearsion/translator.rb +11 -0
- data/lib/adhearsion/translator/asterisk.rb +234 -0
- data/lib/adhearsion/translator/asterisk/agi_app.rb +17 -0
- data/lib/adhearsion/translator/asterisk/agi_command.rb +45 -0
- data/lib/adhearsion/translator/asterisk/ami_error_converter.rb +20 -0
- data/lib/adhearsion/translator/asterisk/call.rb +416 -0
- data/lib/adhearsion/translator/asterisk/channel.rb +43 -0
- data/lib/adhearsion/translator/asterisk/component.rb +88 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk.rb +15 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk/agi_command.rb +42 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk/ami_action.rb +68 -0
- data/lib/adhearsion/translator/asterisk/component/composed_prompt.rb +76 -0
- data/lib/adhearsion/translator/asterisk/component/dtmf_recognizer.rb +137 -0
- data/lib/adhearsion/translator/asterisk/component/input.rb +34 -0
- data/lib/adhearsion/translator/asterisk/component/input_component.rb +90 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_native_prompt.rb +71 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_prompt.rb +55 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_recog_prompt.rb +165 -0
- data/lib/adhearsion/translator/asterisk/component/output.rb +233 -0
- data/lib/adhearsion/translator/asterisk/component/record.rb +101 -0
- data/lib/adhearsion/translator/asterisk/component/stop_by_redirect.rb +30 -0
- data/lib/adhearsion/translator/asterisk/unimrcp_app.rb +28 -0
- data/lib/adhearsion/uri_list.rb +21 -0
- data/lib/adhearsion/version.rb +1 -1
- data/spec/adhearsion/call_controller/dial_spec.rb +79 -1420
- data/spec/adhearsion/call_controller/input_spec.rb +1141 -237
- data/spec/adhearsion/call_controller/output/async_player_spec.rb +10 -10
- data/spec/adhearsion/call_controller/output/player_spec.rb +8 -8
- data/spec/adhearsion/call_controller/output_spec.rb +162 -215
- data/spec/adhearsion/call_controller/record_spec.rb +15 -16
- data/spec/adhearsion/call_controller_spec.rb +23 -40
- data/spec/adhearsion/call_spec.rb +123 -129
- data/spec/adhearsion/calls_spec.rb +3 -3
- data/spec/adhearsion/configuration_spec.rb +94 -108
- data/spec/adhearsion/event/answered_spec.rb +50 -0
- data/spec/adhearsion/event/asterisk/Find Results +402 -0
- data/spec/adhearsion/event/asterisk/ami_spec.rb +81 -0
- data/spec/adhearsion/event/complete_spec.rb +176 -0
- data/spec/adhearsion/event/dtmf_spec.rb +35 -0
- data/spec/adhearsion/event/end_spec.rb +85 -0
- data/spec/adhearsion/event/input_timers_started_spec.rb +19 -0
- data/spec/adhearsion/event/joined_spec.rb +53 -0
- data/spec/adhearsion/event/offer_spec.rb +106 -0
- data/spec/adhearsion/event/ringing_spec.rb +50 -0
- data/spec/adhearsion/event/started_speaking_spec.rb +37 -0
- data/spec/adhearsion/event/stopped_speaking_spec.rb +37 -0
- data/spec/adhearsion/event/unjoined_spec.rb +48 -0
- data/spec/adhearsion/event/untitled +0 -0
- data/spec/adhearsion/events_spec.rb +19 -45
- data/spec/adhearsion/initializer_spec.rb +12 -184
- data/spec/adhearsion/logging_spec.rb +5 -20
- data/spec/adhearsion/outbound_call_spec.rb +13 -13
- data/spec/adhearsion/plugin_spec.rb +3 -4
- data/spec/adhearsion/protocol_error_spec.rb +91 -0
- data/spec/adhearsion/rayo/client/component_registry_spec.rb +26 -0
- data/spec/adhearsion/rayo/client_spec.rb +134 -0
- data/spec/adhearsion/rayo/command/accept_spec.rb +63 -0
- data/spec/adhearsion/rayo/command/answer_spec.rb +73 -0
- data/spec/adhearsion/rayo/command/dial_spec.rb +156 -0
- data/spec/adhearsion/rayo/command/hangup_spec.rb +63 -0
- data/spec/adhearsion/rayo/command/join_spec.rb +158 -0
- data/spec/adhearsion/rayo/command/mute_spec.rb +32 -0
- data/spec/adhearsion/rayo/command/redirect_spec.rb +89 -0
- data/spec/adhearsion/rayo/command/reject_spec.rb +117 -0
- data/spec/adhearsion/rayo/command/unjoin_spec.rb +82 -0
- data/spec/adhearsion/rayo/command/unmute_spec.rb +32 -0
- data/spec/adhearsion/rayo/command_node_spec.rb +101 -0
- data/spec/adhearsion/rayo/component/asterisk/agi/command_spec.rb +111 -0
- data/spec/adhearsion/rayo/component/asterisk/ami/action_spec.rb +173 -0
- data/spec/adhearsion/rayo/component/component_node_spec.rb +110 -0
- data/spec/adhearsion/rayo/component/input_spec.rb +715 -0
- data/spec/adhearsion/rayo/component/output_spec.rb +1030 -0
- data/spec/adhearsion/rayo/component/prompt_spec.rb +171 -0
- data/spec/adhearsion/rayo/component/receive_fax_spec.rb +136 -0
- data/spec/adhearsion/rayo/component/record_spec.rb +497 -0
- data/spec/adhearsion/rayo/component/send_fax_spec.rb +144 -0
- data/spec/adhearsion/rayo/connection/asterisk_spec.rb +118 -0
- data/spec/adhearsion/rayo/connection/xmpp_spec.rb +449 -0
- data/spec/adhearsion/rayo/initializer_spec.rb +353 -0
- data/spec/adhearsion/rayo/ref_spec.rb +168 -0
- data/spec/adhearsion/rayo_spec.rb +7 -0
- data/spec/adhearsion/router/route_spec.rb +1 -1
- data/spec/adhearsion/statistics_spec.rb +2 -5
- data/spec/adhearsion/translator/asterisk/call_spec.rb +2047 -0
- data/spec/adhearsion/translator/asterisk/component/asterisk/agi_command_spec.rb +256 -0
- data/spec/adhearsion/translator/asterisk/component/asterisk/ami_action_spec.rb +151 -0
- data/spec/adhearsion/translator/asterisk/component/composed_prompt_spec.rb +257 -0
- data/spec/adhearsion/translator/asterisk/component/input_spec.rb +571 -0
- data/spec/adhearsion/translator/asterisk/component/mrcp_native_prompt_spec.rb +774 -0
- data/spec/adhearsion/translator/asterisk/component/mrcp_prompt_spec.rb +1244 -0
- data/spec/adhearsion/translator/asterisk/component/output_spec.rb +1850 -0
- data/spec/adhearsion/translator/asterisk/component/record_spec.rb +426 -0
- data/spec/adhearsion/translator/asterisk/component/stop_by_redirect_spec.rb +62 -0
- data/spec/adhearsion/translator/asterisk/component_spec.rb +83 -0
- data/spec/adhearsion/translator/asterisk_spec.rb +685 -0
- data/spec/adhearsion/uri_list_spec.rb +88 -0
- data/spec/adhearsion_spec.rb +89 -14
- data/spec/fixtures/locale/en.yml +13 -0
- data/spec/fixtures/locale/it.yml +13 -0
- data/spec/spec_helper.rb +18 -5
- data/spec/support/call_controller_test_helpers.rb +3 -2
- data/spec/support/initializer_stubs.rb +3 -1
- data/spec/support/punchblock_examples.rb +65 -0
- data/spec/support/punchblock_mocks.rb +12 -0
- metadata +412 -70
- data/features/cli_daemon.feature +0 -20
- data/features/cli_restart.feature +0 -52
- data/features/cli_stop.feature +0 -50
- data/lib/adhearsion/call_controller/menu_dsl.rb +0 -21
- data/lib/adhearsion/call_controller/menu_dsl/array_match_calculator.rb +0 -26
- data/lib/adhearsion/call_controller/menu_dsl/calculated_match.rb +0 -43
- data/lib/adhearsion/call_controller/menu_dsl/calculated_match_collection.rb +0 -45
- data/lib/adhearsion/call_controller/menu_dsl/fixnum_match_calculator.rb +0 -11
- data/lib/adhearsion/call_controller/menu_dsl/match_calculator.rb +0 -40
- data/lib/adhearsion/call_controller/menu_dsl/menu.rb +0 -207
- data/lib/adhearsion/call_controller/menu_dsl/menu_builder.rb +0 -92
- data/lib/adhearsion/call_controller/menu_dsl/range_match_calculator.rb +0 -60
- data/lib/adhearsion/call_controller/menu_dsl/string_match_calculator.rb +0 -25
- data/lib/adhearsion/call_controller/utility.rb +0 -77
- data/lib/adhearsion/foundation/custom_daemonizer.rb +0 -52
- data/lib/adhearsion/punchblock_plugin.rb +0 -63
- data/scripts/cloc-1.64.pl +0 -10483
- data/spec/adhearsion/call_controller/menu_dsl/array_match_calculator_spec.rb +0 -76
- data/spec/adhearsion/call_controller/menu_dsl/calculated_match_collection_spec.rb +0 -60
- data/spec/adhearsion/call_controller/menu_dsl/calculated_match_spec.rb +0 -61
- data/spec/adhearsion/call_controller/menu_dsl/fixnum_match_calculator_spec.rb +0 -39
- data/spec/adhearsion/call_controller/menu_dsl/match_calculator_spec.rb +0 -17
- data/spec/adhearsion/call_controller/menu_dsl/menu_builder_spec.rb +0 -165
- data/spec/adhearsion/call_controller/menu_dsl/menu_spec.rb +0 -420
- data/spec/adhearsion/call_controller/menu_dsl/range_match_calculator_spec.rb +0 -32
- data/spec/adhearsion/call_controller/menu_dsl/string_match_calculator_spec.rb +0 -40
- data/spec/adhearsion/call_controller/utility_spec.rb +0 -90
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +0 -356
- data/spec/adhearsion/punchblock_plugin_spec.rb +0 -59
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
%w{
|
|
4
|
+
timeout
|
|
5
|
+
blather/client/dsl
|
|
6
|
+
adhearsion/core_ext/blather/stanza
|
|
7
|
+
adhearsion/core_ext/blather/stanza/presence
|
|
8
|
+
adhearsion/rayo/connection/generic_connection
|
|
9
|
+
}.each { |f| require f }
|
|
10
|
+
|
|
11
|
+
module Adhearsion
|
|
12
|
+
module Rayo
|
|
13
|
+
module Connection
|
|
14
|
+
class XMPP < GenericConnection
|
|
15
|
+
include Blather::DSL
|
|
16
|
+
attr_accessor :event_handler, :root_domain
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# Initialize the required connection attributes
|
|
20
|
+
#
|
|
21
|
+
# @param [Hash] options
|
|
22
|
+
# @option options [String] :username client JID
|
|
23
|
+
# @option options [String] :password XMPP password
|
|
24
|
+
# @option options [String] :rayo_domain the domain on which Rayo is running
|
|
25
|
+
# @option options [Numeric, Optional] :write_timeout for which to wait on a command response
|
|
26
|
+
# @option options [Numeric, Optional] :connection_timeout for which to wait on a connection being established
|
|
27
|
+
# @option options [Numeric, nil, Optional] :ping_period interval in seconds on which to ping the server. Nil or false to disable
|
|
28
|
+
#
|
|
29
|
+
def initialize(options = {})
|
|
30
|
+
raise ArgumentError unless (@username = options[:username]) && options[:password]
|
|
31
|
+
|
|
32
|
+
setup(*[:username, :password, :host, :port, :certs, :connection_timeout].map { |key| options.delete key })
|
|
33
|
+
|
|
34
|
+
@root_domain = Blather::JID.new(options[:root_domain] || options[:rayo_domain] || @username).domain
|
|
35
|
+
|
|
36
|
+
@joined_mixers = []
|
|
37
|
+
|
|
38
|
+
@ping_period = options.has_key?(:ping_period) ? options[:ping_period] : 60
|
|
39
|
+
|
|
40
|
+
Blather.logger = logger
|
|
41
|
+
Blather.default_log_level = :trace if Blather.respond_to? :default_log_level
|
|
42
|
+
|
|
43
|
+
register_handlers
|
|
44
|
+
|
|
45
|
+
super()
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def write(command, options = {})
|
|
49
|
+
iq = prep_command_for_execution command, options
|
|
50
|
+
command.request!
|
|
51
|
+
client.write_with_handler iq do |response|
|
|
52
|
+
if response.result?
|
|
53
|
+
handle_iq_result response, command
|
|
54
|
+
elsif response.error?
|
|
55
|
+
handle_error response, command
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def prep_command_for_execution(command, options = {})
|
|
61
|
+
command.connection = self
|
|
62
|
+
command.target_call_id ||= options[:call_id]
|
|
63
|
+
command.target_mixer_name ||= options[:mixer_name]
|
|
64
|
+
command.domain ||= options[:domain]
|
|
65
|
+
command.component_id ||= options[:component_id]
|
|
66
|
+
if command.is_a?(Command::Join) && command.mixer_name
|
|
67
|
+
@joined_mixers << command.mixer_name
|
|
68
|
+
end
|
|
69
|
+
create_iq(jid_for_command(command), command.request_id).tap do |iq|
|
|
70
|
+
command.to_rayo(iq)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def send_message(call_id, domain, body, options = {})
|
|
75
|
+
jid = Blather::JID.new(call_id, domain || root_domain).to_s
|
|
76
|
+
message = Blather::Stanza::Message.new(jid, body, :normal)
|
|
77
|
+
message.subject = options[:subject]
|
|
78
|
+
client.write message
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# Fire up the connection
|
|
83
|
+
#
|
|
84
|
+
def run
|
|
85
|
+
connect
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def connect
|
|
89
|
+
begin
|
|
90
|
+
EM.run { client.run }
|
|
91
|
+
rescue Blather::Stream::ConnectionFailed, Blather::Stream::ConnectionTimeout, Blather::StreamError => e
|
|
92
|
+
raise DisconnectedError.new(e.class.to_s, e.message)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def stop
|
|
97
|
+
client.close if client.connected?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def connected?
|
|
101
|
+
client.connected?
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def ready!
|
|
105
|
+
send_presence :chat
|
|
106
|
+
super
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def not_ready!
|
|
110
|
+
send_presence :dnd
|
|
111
|
+
super
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def new_call_uri
|
|
115
|
+
"xmpp:#{Adhearsion.new_uuid}@#{root_domain}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
|
|
120
|
+
def jid_for_command(command)
|
|
121
|
+
return root_domain if command.is_a?(Command::Dial)
|
|
122
|
+
|
|
123
|
+
if command.target_call_id
|
|
124
|
+
node = command.target_call_id
|
|
125
|
+
elsif command.target_mixer_name
|
|
126
|
+
node = command.target_mixer_name
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
Blather::JID.new(node, command.domain || root_domain, command.component_id).to_s
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def send_presence(presence)
|
|
133
|
+
status = Blather::Stanza::Presence::Status.new presence
|
|
134
|
+
status.to = root_domain
|
|
135
|
+
client.write status
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def handle_presence(p)
|
|
139
|
+
throw :pass unless p.rayo_event?
|
|
140
|
+
event = p.event
|
|
141
|
+
event.connection = self
|
|
142
|
+
event.domain = p.from.domain
|
|
143
|
+
event.transport = "xmpp"
|
|
144
|
+
if @joined_mixers.include?(p.call_id)
|
|
145
|
+
event.target_mixer_name = p.call_id
|
|
146
|
+
else
|
|
147
|
+
event.target_call_id = p.call_id
|
|
148
|
+
end
|
|
149
|
+
event_handler.call event
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def handle_iq_result(iq, command)
|
|
153
|
+
command.response = iq.rayo_node.is_a?(Ref) ? iq.rayo_node : true
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def handle_error(iq, command = nil)
|
|
157
|
+
e = Blather::StanzaError.import iq
|
|
158
|
+
protocol_error = ProtocolError.new.setup e.name, e.text, iq.call_id, iq.component_id
|
|
159
|
+
command.response = protocol_error if command
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def register_handlers
|
|
163
|
+
# Push a message to the queue and the log that we connected
|
|
164
|
+
when_ready do
|
|
165
|
+
event_handler.call Connected.new
|
|
166
|
+
logger.info "Connected to XMPP as #{@username}"
|
|
167
|
+
@rayo_ping = EM::PeriodicTimer.new(@ping_period) { ping_rayo } if @ping_period
|
|
168
|
+
throw :pass
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
disconnected do
|
|
172
|
+
@rayo_ping.cancel if @rayo_ping
|
|
173
|
+
raise DisconnectedError
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Read/handle presence requests. This is how we get events.
|
|
177
|
+
presence do |msg|
|
|
178
|
+
handle_presence msg
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def ping_rayo
|
|
183
|
+
client.write_with_handler Blather::Stanza::Iq::Ping.new(:get, root_domain) do |response|
|
|
184
|
+
begin
|
|
185
|
+
handle_error response if response.is_a? Blather::BlatherError
|
|
186
|
+
rescue ProtocolError => e
|
|
187
|
+
raise unless e.name == :feature_not_implemented
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def create_iq(jid, id)
|
|
193
|
+
Blather::Stanza::Iq.new :set, jid, id
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'adhearsion/error'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module Rayo
|
|
7
|
+
##
|
|
8
|
+
# This exception may be raised if the connection to the server is interrupted.
|
|
9
|
+
class DisconnectedError < Error
|
|
10
|
+
attr_accessor :cause, :message
|
|
11
|
+
|
|
12
|
+
def initialize(cause = nil, message = nil)
|
|
13
|
+
@cause, @message = cause, message
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_s
|
|
17
|
+
"#<#{self.class}: cause=#{cause.inspect} message=#{message.inspect}"
|
|
18
|
+
end
|
|
19
|
+
alias :inspect :to_s
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -4,7 +4,7 @@ require 'blather'
|
|
|
4
4
|
require 'active_support/core_ext/class/attribute_accessors'
|
|
5
5
|
|
|
6
6
|
module Adhearsion
|
|
7
|
-
|
|
7
|
+
module Rayo
|
|
8
8
|
class Initializer
|
|
9
9
|
cattr_accessor :config, :client, :dispatcher, :attempts
|
|
10
10
|
|
|
@@ -12,10 +12,10 @@ module Adhearsion
|
|
|
12
12
|
|
|
13
13
|
class << self
|
|
14
14
|
def init
|
|
15
|
-
self.config = Adhearsion.config
|
|
15
|
+
self.config = Adhearsion.config.core
|
|
16
16
|
|
|
17
17
|
username = self.config.username
|
|
18
|
-
if (self.config.
|
|
18
|
+
if (self.config.type || :xmpp) == :xmpp
|
|
19
19
|
username = Blather::JID.new username
|
|
20
20
|
username = Blather::JID.new username.node, username.domain, resource unless username.resource
|
|
21
21
|
username = username.to_s
|
|
@@ -31,9 +31,9 @@ module Adhearsion
|
|
|
31
31
|
:root_domain => self.config.root_domain
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
self.client =
|
|
34
|
+
self.client = Adhearsion.client_with_connection self.config.type, connection_options
|
|
35
35
|
|
|
36
|
-
# Tell the
|
|
36
|
+
# Tell the connection that we are ready to process calls.
|
|
37
37
|
Events.register_callback :after_initialized do
|
|
38
38
|
connection.ready!
|
|
39
39
|
end
|
|
@@ -49,25 +49,25 @@ module Adhearsion
|
|
|
49
49
|
client.stop
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
# Handle events from
|
|
52
|
+
# Handle events from connection via events system
|
|
53
53
|
self.client.register_event_handler do |event|
|
|
54
54
|
handle_event event
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
Events.
|
|
58
|
-
logger.info "Connected to
|
|
57
|
+
Events.rayo Adhearsion::Rayo::Connection::Connected do |event|
|
|
58
|
+
logger.info "Connected to Rayo server"
|
|
59
59
|
self.attempts = 0
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
Events.
|
|
62
|
+
Events.rayo Adhearsion::Event::Offer do |offer|
|
|
63
63
|
dispatch_offer offer
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
Events.
|
|
66
|
+
Events.rayo proc { |e| e.respond_to?(:source) }, :source do |event|
|
|
67
67
|
event.source.trigger_event_handler event
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
Events.
|
|
70
|
+
Events.rayo proc { |e| e.respond_to?(:target_call_id) }, :target_call_id do |event|
|
|
71
71
|
dispatch_call_event event
|
|
72
72
|
end
|
|
73
73
|
end
|
|
@@ -81,7 +81,7 @@ module Adhearsion
|
|
|
81
81
|
m = Mutex.new
|
|
82
82
|
blocker = ConditionVariable.new
|
|
83
83
|
|
|
84
|
-
Events.
|
|
84
|
+
Events.rayo Adhearsion::Rayo::Connection::Connected do
|
|
85
85
|
Adhearsion::Process.booted
|
|
86
86
|
m.synchronize { blocker.broadcast }
|
|
87
87
|
end
|
|
@@ -104,7 +104,7 @@ module Adhearsion
|
|
|
104
104
|
def connect_to_server
|
|
105
105
|
logger.info "Starting connection to server"
|
|
106
106
|
client.run
|
|
107
|
-
rescue
|
|
107
|
+
rescue Adhearsion::Rayo::DisconnectedError => e
|
|
108
108
|
# We only care about disconnects if the process is up or booting
|
|
109
109
|
return unless [:booting, :running].include? Adhearsion::Process.state_name
|
|
110
110
|
|
|
@@ -121,7 +121,7 @@ module Adhearsion
|
|
|
121
121
|
logger.error "Connection lost. Attempting reconnect #{self.attempts} of #{self.config.reconnect_attempts}"
|
|
122
122
|
sleep self.config.reconnect_timer
|
|
123
123
|
retry
|
|
124
|
-
rescue
|
|
124
|
+
rescue Adhearsion::ProtocolError => e
|
|
125
125
|
logger.fatal "The connection failed due to a protocol error: #{e.name}."
|
|
126
126
|
raise e
|
|
127
127
|
end
|
|
@@ -152,9 +152,9 @@ module Adhearsion
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def handle_event(event)
|
|
155
|
-
Events.trigger :
|
|
155
|
+
Events.trigger :rayo, event
|
|
156
156
|
case event
|
|
157
|
-
when
|
|
157
|
+
when Adhearsion::Event::Asterisk::AMI
|
|
158
158
|
Events.trigger :ami, event
|
|
159
159
|
end
|
|
160
160
|
end
|
|
@@ -173,6 +173,6 @@ module Adhearsion
|
|
|
173
173
|
client.connection
|
|
174
174
|
end
|
|
175
175
|
end
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
|
4
|
+
require 'virtus'
|
|
5
|
+
|
|
6
|
+
require 'adhearsion/rayo'
|
|
7
|
+
|
|
8
|
+
module Adhearsion
|
|
9
|
+
module Rayo
|
|
10
|
+
class RayoNode
|
|
11
|
+
include Virtus.model
|
|
12
|
+
|
|
13
|
+
@@registrations = {}
|
|
14
|
+
|
|
15
|
+
class_attribute :registered_ns, :registered_name
|
|
16
|
+
|
|
17
|
+
attribute :target_call_id
|
|
18
|
+
attribute :target_mixer_name
|
|
19
|
+
attribute :component_id
|
|
20
|
+
attribute :source_uri
|
|
21
|
+
attribute :domain
|
|
22
|
+
attribute :transport
|
|
23
|
+
attribute :timestamp, DateTime, default: ->(*) { DateTime.now }
|
|
24
|
+
|
|
25
|
+
attr_accessor :connection, :client, :original_component
|
|
26
|
+
|
|
27
|
+
# Register a new stanza class to a name and/or namespace
|
|
28
|
+
#
|
|
29
|
+
# This registers a namespace that is used when looking
|
|
30
|
+
# up the class name of the object to instantiate when a new
|
|
31
|
+
# stanza is received
|
|
32
|
+
#
|
|
33
|
+
# @param [#to_s] name the name of the node
|
|
34
|
+
# @param [String, nil] ns the namespace the node belongs to
|
|
35
|
+
def self.register(name, ns = nil)
|
|
36
|
+
self.registered_name = name.to_s
|
|
37
|
+
self.registered_ns = ns.is_a?(Symbol) ? RAYO_NAMESPACES[ns] : ns
|
|
38
|
+
@@registrations[[self.registered_name, self.registered_ns]] = self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Find the class to use given the name and namespace of a stanza
|
|
42
|
+
#
|
|
43
|
+
# @param [#to_s] name the name to lookup
|
|
44
|
+
# @param [String, nil] xmlns the namespace the node belongs to
|
|
45
|
+
# @return [Class, nil] the class appropriate for the name/ns combination
|
|
46
|
+
def self.class_from_registration(name, ns = nil)
|
|
47
|
+
@@registrations[[name.to_s, ns]]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Import an XML::Node to the appropriate class
|
|
51
|
+
#
|
|
52
|
+
# Looks up the class the node should be then creates it based on the
|
|
53
|
+
# elements of the XML::Node
|
|
54
|
+
# @param [XML::Node] node the node to import
|
|
55
|
+
# @return the appropriate object based on the node name and namespace
|
|
56
|
+
def self.from_xml(node, call_id = nil, component_id = nil, uri = nil, timestamp = nil)
|
|
57
|
+
ns = (node.namespace.href if node.namespace)
|
|
58
|
+
klass = class_from_registration(node.name, ns)
|
|
59
|
+
if klass && klass != self
|
|
60
|
+
klass.from_xml node, call_id, component_id
|
|
61
|
+
else
|
|
62
|
+
new.inherit node
|
|
63
|
+
end.tap do |event|
|
|
64
|
+
event.target_call_id = call_id
|
|
65
|
+
event.component_id = component_id
|
|
66
|
+
event.source_uri = uri
|
|
67
|
+
event.timestamp = timestamp if timestamp
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def inherit(xml_node)
|
|
72
|
+
xml_node.attributes.each do |key, attr_node|
|
|
73
|
+
setter_method = "#{key.gsub('-', '_')}="
|
|
74
|
+
send setter_method, xml_node[key] if respond_to?(setter_method)
|
|
75
|
+
end
|
|
76
|
+
self
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def inspect
|
|
80
|
+
"#<#{self.class} #{to_hash.map { |k, v| "#{k}=#{v.inspect}" }.compact * ', '}>"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def ==(o)
|
|
84
|
+
o.is_a?(self.class) && self.comparable_attributes == o.comparable_attributes
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
##
|
|
88
|
+
# @return [RayoNode] the original command issued that lead to this event
|
|
89
|
+
#
|
|
90
|
+
def source
|
|
91
|
+
@source ||= client.find_component_by_uri source_uri if client && source_uri
|
|
92
|
+
@source ||= original_component
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def rayo_attributes
|
|
96
|
+
{}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def rayo_children(root)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def to_rayo(parent = nil)
|
|
103
|
+
parent = parent.parent if parent.is_a?(Nokogiri::XML::Builder)
|
|
104
|
+
Nokogiri::XML::Builder.with(parent) do |xml|
|
|
105
|
+
xml.send(registered_name,
|
|
106
|
+
{xmlns: registered_ns}.merge(rayo_attributes.delete_if { |k,v| v.nil? })) do |root|
|
|
107
|
+
rayo_children root
|
|
108
|
+
end
|
|
109
|
+
end.doc.root
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def to_xml
|
|
113
|
+
to_rayo.to_xml
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
alias :to_s :inspect
|
|
117
|
+
|
|
118
|
+
protected
|
|
119
|
+
|
|
120
|
+
def comparable_attributes
|
|
121
|
+
to_hash.tap do |hash|
|
|
122
|
+
hash.delete :timestamp
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|