ragi 1.0.0
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.
- data/CHANGELOG +12 -0
- data/RAGI Overview_files/filelist.xml +5 -0
- data/RAGI Overview_files/image001.gif +0 -0
- data/README +114 -0
- data/call_connection.rb +515 -0
- data/call_handler.rb +362 -0
- data/call_initiate.rb +188 -0
- data/call_server.rb +147 -0
- data/config.rb +68 -0
- data/example-call-audio.mp3 +0 -0
- data/ragi.gempsec +23 -0
- data/sample-apps/simon/simon_handler.rb +94 -0
- data/sample-apps/simon/sounds/README +9 -0
- data/sample-apps/simon/sounds/simon-1.gsm +0 -0
- data/sample-apps/simon/sounds/simon-2.gsm +0 -0
- data/sample-apps/simon/sounds/simon-3.gsm +0 -0
- data/sample-apps/simon/sounds/simon-4.gsm +0 -0
- data/sample-apps/simon/sounds/simon-5.gsm +0 -0
- data/sample-apps/simon/sounds/simon-6.gsm +0 -0
- data/sample-apps/simon/sounds/simon-7.gsm +0 -0
- data/sample-apps/simon/sounds/simon-8.gsm +0 -0
- data/sample-apps/simon/sounds/simon-9.gsm +0 -0
- data/sample-apps/simon/sounds/simon-again.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-again.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-beep.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-gameover.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-high.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-low.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-medium.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-score.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep-welcome.gsm +0 -0
- data/sample-apps/simon/sounds/simon-beep.gsm +0 -0
- data/sample-apps/simon/sounds/simon-gameover.gsm +0 -0
- data/sample-apps/simon/sounds/simon-goodbye.gsm +0 -0
- data/sample-apps/simon/sounds/simon-high.gsm +0 -0
- data/sample-apps/simon/sounds/simon-low.gsm +0 -0
- data/sample-apps/simon/sounds/simon-medium.gsm +0 -0
- data/sample-apps/simon/sounds/simon-score.gsm +0 -0
- data/sample-apps/simon/sounds/simon-welcome.gsm +0 -0
- data/start_ragi.rb +41 -0
- data/test.rb +109 -0
- metadata +77 -0
data/call_server.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
#
|
2
|
+
# RAGI - Ruby classes for implementing an AGI server for Asterisk
|
3
|
+
# The BSD License for RAGI follows.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2005, SNAPVINE LLC (www.snapvine.com)
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of SNAPVINE nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
require 'webrick/config'
|
32
|
+
require 'webrick/log'
|
33
|
+
require 'webrick/server'
|
34
|
+
require 'ragi/call_handler'
|
35
|
+
require 'ragi/call_connection'
|
36
|
+
require 'ragi/config'
|
37
|
+
require 'thread'
|
38
|
+
|
39
|
+
module RAGI
|
40
|
+
VERSION = "0.0.1"
|
41
|
+
|
42
|
+
@globalConfig = nil
|
43
|
+
|
44
|
+
def self.LOGGER
|
45
|
+
@logger ||= WEBrick::Log::new
|
46
|
+
@logger
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.LOGGER=(logger)
|
50
|
+
@logger = logger
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.globalConfig
|
54
|
+
# This assignment will make a dup
|
55
|
+
@globalConfig ||= RAGI::Config::Globals
|
56
|
+
@globalConfig
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.globalConfig=(newConfig)
|
60
|
+
@globalConfig = newConfig.dup()
|
61
|
+
end
|
62
|
+
|
63
|
+
class CallServer
|
64
|
+
@incomingcallsocket = nil
|
65
|
+
|
66
|
+
# 4573 = asterisk AGI
|
67
|
+
# RAGI::CallHandler - default handler
|
68
|
+
|
69
|
+
def initialize(config = {}, default = RAGI::Config::Standard)
|
70
|
+
@config = default.dup.update(config)
|
71
|
+
@config[:Logger] ||= WEBrick::Log::new
|
72
|
+
@config[:ParentStopCallback] = @config[:StopCallback] if @config[:StopCallback]
|
73
|
+
@config[:StopCallback] = method('shutdown_done')
|
74
|
+
|
75
|
+
RAGI.LOGGER = @config[:Logger]
|
76
|
+
|
77
|
+
@mutex = Mutex.new
|
78
|
+
@signal = ConditionVariable.new
|
79
|
+
@running = true
|
80
|
+
|
81
|
+
if (@incomingcallsocket == nil)
|
82
|
+
begin
|
83
|
+
# code to executed in a thread
|
84
|
+
RAGI.LOGGER.info("#{self.class.name}: default-handler=#{@config[:DefaultHandler].to_s} port=#{@config[:Port]}")
|
85
|
+
@incomingcallsocket = WEBrick::GenericServer.new( @config )
|
86
|
+
|
87
|
+
@incomingcallsocket.start{ |sock|
|
88
|
+
cc = CallConnection.new(sock)
|
89
|
+
|
90
|
+
route = {
|
91
|
+
:handler => @config[:DefaultHandler],
|
92
|
+
:action => :dialup
|
93
|
+
}
|
94
|
+
|
95
|
+
# the default call handler comes from config environment.rb
|
96
|
+
|
97
|
+
if (cc.agi_url != nil && cc.agi_url != '/')
|
98
|
+
route = CallHandler.route(cc.agi_url)
|
99
|
+
end
|
100
|
+
RAGI.LOGGER.info("#{self.class.name}: processing call with #{route[:handler].to_s}")
|
101
|
+
|
102
|
+
CallHandler.process(route, cc)
|
103
|
+
|
104
|
+
# todo: Catch exceptions and say something to the user
|
105
|
+
# before we disconnect them. Something like this maybe:
|
106
|
+
#
|
107
|
+
# rescue StandardError => err
|
108
|
+
# if (cc) then
|
109
|
+
# cc.play_sound('tc/std/sorry-error')
|
110
|
+
# cc.hang_up()
|
111
|
+
# end
|
112
|
+
# raise
|
113
|
+
# end
|
114
|
+
}
|
115
|
+
RAGI.LOGGER.info("#{self.class.name}: server shutdown port=#{@config[:Port]}")
|
116
|
+
|
117
|
+
rescue StandardError => err
|
118
|
+
RAGI.LOGGER.error("#{err.message}")
|
119
|
+
RAGI.LOGGER.error(err.backtrace.join("\n"))
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def shutdown
|
126
|
+
@incomingcallsocket.shutdown
|
127
|
+
end
|
128
|
+
|
129
|
+
def shutdown_done
|
130
|
+
RAGI.LOGGER.debug("#{self.class.name}: Shutdown complete")
|
131
|
+
|
132
|
+
@config[:ParentStopCallback].call if @config[:ParentStopCallback]
|
133
|
+
@mutex.synchronize do
|
134
|
+
@running = false
|
135
|
+
@signal.signal
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def join
|
140
|
+
@mutex.synchronize do
|
141
|
+
if @running
|
142
|
+
@signal.wait(@mutex)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
data/config.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
# RAGI - Ruby classes for implementing an AGI server for Asterisk
|
3
|
+
# The BSD License for RAGI follows.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2005, SNAPVINE LLC (www.snapvine.com)
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of SNAPVINE nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# config.rb -- Default configurations.
|
32
|
+
#
|
33
|
+
|
34
|
+
require 'webrick/config'
|
35
|
+
require 'ragi/call_handler'
|
36
|
+
|
37
|
+
module RAGI
|
38
|
+
|
39
|
+
DEFAULT_PORT = 4573
|
40
|
+
|
41
|
+
module Config
|
42
|
+
|
43
|
+
# for HTTPServer, HTTPRequest, HTTPResponse ...
|
44
|
+
Standard = WEBrick::Config::General.dup.update(
|
45
|
+
:Port => RAGI::DEFAULT_PORT,
|
46
|
+
:HandlerMap => {}
|
47
|
+
)
|
48
|
+
|
49
|
+
Globals = {
|
50
|
+
# Name of the box running the agi server, so that asterisk can find it
|
51
|
+
# by default this will use your Ruby server's name
|
52
|
+
"agiServer" => `hostname`.strip(),
|
53
|
+
|
54
|
+
# Path to use for saving outgoing call files
|
55
|
+
"outgoingCallPath" =>
|
56
|
+
ENV['RAGI_OUT_CALL_PATH'] ? ENV['RAGI_OUT_CALL_PATH'] : "var/spool/asterisk/outgoing",
|
57
|
+
|
58
|
+
# Path to use for saving wakeup call files
|
59
|
+
"wakeupCallPath" =>
|
60
|
+
ENV['RAGI_WAKEUP_CALL_PATH'] ? ENV['RAGI_WAKEUP_CALL_PATH'] : "var/spool/asterisk/wakeups",
|
61
|
+
|
62
|
+
# Path to the built-in sound files relative to the SIP server.
|
63
|
+
"sipSoundPath" =>
|
64
|
+
ENV['RAGI_SIP_SOUND_PATH'] ? ENV['RAGI_SIP_SOUND_PATH'] : "var/lib/asterisk/sounds"
|
65
|
+
}
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
Binary file
|
data/ragi.gempsec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake"
|
3
|
+
|
4
|
+
spec = Gem::Specification.new do |gem|
|
5
|
+
gem.name = "ragi"
|
6
|
+
gem.version = "1.0.0"
|
7
|
+
gem.author = "Joe Heitzeberg"
|
8
|
+
gem.email = "joe_AT_snapvine.com"
|
9
|
+
gem.homepage = "http://rubyforge.org/projects/ragi"
|
10
|
+
gem.platform = Gem::Platform::RUBY
|
11
|
+
gem.summary = "RAGI allows you to create useful telephony applications using Asterisk and Ruby [on Rails]."
|
12
|
+
gem.description = "RAGI allows you to create useful telephony applications using Asterisk and Ruby [on Rails]. Please see the included README file for more information"
|
13
|
+
gem.has_rdoc = false
|
14
|
+
|
15
|
+
gem.files = FileList['example-call-audio.mp3', 'ragi.gempsec', 'CHANGELOG', 'README', '*.rb', 'RAGI Overview_files/*', 'sample-apps/simon/*.rb', 'sample-apps/simon/sounds/README', 'sample-apps/simon/sounds/*.gsm'].to_a
|
16
|
+
gem.files.reject! { |fn| fn.include? "SVN" }
|
17
|
+
end
|
18
|
+
|
19
|
+
if $0 == __FILE__
|
20
|
+
Gem.manage_gems
|
21
|
+
Gem::Builder.new(spec).build
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# RAGI -- Ruby Asterisk Gateway Interface
|
2
|
+
# See ragi.sourceforge.net for more information.
|
3
|
+
# Sponsored by SnapVine, Inc (www.snapvine.com)
|
4
|
+
#
|
5
|
+
# Class: SimonHandler
|
6
|
+
# Description: this call handler implements a simple memory game over the phone.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'ragi/call_handler'
|
10
|
+
|
11
|
+
class SimonHandler < RAGI::CallHandler
|
12
|
+
APP_NAME = 'simon'
|
13
|
+
|
14
|
+
# When the RAGI server connects from Asterisk over AGI to our app, it calls this method.
|
15
|
+
def dialup
|
16
|
+
answer # answer the call
|
17
|
+
wait(1) # give it 1 seconds to make sure the connection is established
|
18
|
+
|
19
|
+
|
20
|
+
playAgain = true
|
21
|
+
while (playAgain)
|
22
|
+
instructions # tell the caller how to play the game
|
23
|
+
score = play_game # start the game and play it, returning the score when done
|
24
|
+
announce_score(score) # tell them how they did
|
25
|
+
playAgain = ask_play_again # ask if they want to play again
|
26
|
+
end
|
27
|
+
say_goodbye
|
28
|
+
hang_up #end the call
|
29
|
+
end
|
30
|
+
|
31
|
+
def instructions
|
32
|
+
play_sound("simon-welcome")
|
33
|
+
end
|
34
|
+
|
35
|
+
def play_game
|
36
|
+
|
37
|
+
intArray = [rand(10)]
|
38
|
+
score = 0
|
39
|
+
|
40
|
+
# test the user's memory on the current int array
|
41
|
+
while memory_test(intArray)
|
42
|
+
score += 1
|
43
|
+
|
44
|
+
# grow the array by one digit
|
45
|
+
intArray << rand(10) # choose a number between 0 and 9 inclusive
|
46
|
+
|
47
|
+
wait(1)
|
48
|
+
end
|
49
|
+
|
50
|
+
score
|
51
|
+
end
|
52
|
+
|
53
|
+
def memory_test(intArray)
|
54
|
+
# say each number in the array
|
55
|
+
intArray.each do |number|
|
56
|
+
play_sound("simon-#{number}") # there are sounds like simon-6.gsm
|
57
|
+
end
|
58
|
+
|
59
|
+
# listen for user key presses (number of presses should be == intArray.length)
|
60
|
+
# Note: give about 1 second per key press (intArray.length * 1500)
|
61
|
+
resultStr = get_data("simon-beep", (intArray.length * 1500), intArray.length)
|
62
|
+
|
63
|
+
# Check if what they entered matches the int array
|
64
|
+
if (resultStr == intArray.join("")) # note: join converts from array to string
|
65
|
+
return true
|
66
|
+
else
|
67
|
+
play_sound("simon-gameover")
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def announce_score(score)
|
73
|
+
if (score <= 9)
|
74
|
+
play_sound("simon-score")
|
75
|
+
play_sound("simon-#{score.to_s}")
|
76
|
+
end
|
77
|
+
if (score < 5)
|
78
|
+
play_sound("simon-low")
|
79
|
+
elsif (score < 10)
|
80
|
+
play_sound("simon-medium")
|
81
|
+
else
|
82
|
+
play_sound("simon-high")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def ask_play_again
|
87
|
+
# Give the user three seconds to press a digit
|
88
|
+
return (get_data("simon-again", 3000, 1).length > 0)
|
89
|
+
end
|
90
|
+
|
91
|
+
def say_goodbye
|
92
|
+
play_sound("simon-goodbye")
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
These are the sounds needed for the simon sample app.
|
2
|
+
|
3
|
+
You'll need to copy these sounds directly to the default sounds directory on your Asterisk server (e.g. var/lib/asterisk/sounds/) in order to use the simon game app.
|
4
|
+
|
5
|
+
In the simon call handler, it plays these sounds using the playSound command, e.g.:
|
6
|
+
play_sound("simon-welcome")
|
7
|
+
|
8
|
+
This command tells the asterisk server to play the sound "simon-welcome.gsm" from the asterisk server's default sound location (e.g. var/lib/asterisk/sounds/simon-welcome.gsm)
|
9
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/start_ragi.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#
|
2
|
+
# RAGI - Ruby classes for implementing an AGI server for Asterisk
|
3
|
+
# The BSD License for RAGI follows.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2005, SNAPVINE LLC (www.snapvine.com)
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of SNAPVINE nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
#
|
31
|
+
# Class: start_ragi.rb
|
32
|
+
# This class provides a server to answer incoming AGI requests from Asterisk.
|
33
|
+
# It is configured to run the sample app, Simon.
|
34
|
+
#
|
35
|
+
|
36
|
+
|
37
|
+
require 'ragi/call_server'
|
38
|
+
require 'ragi/sample-apps/simon/simon_handler'
|
39
|
+
|
40
|
+
RAGI::CallServer.new( :DefaultHandler => SimonHandler )
|
41
|
+
|
data/test.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#
|
2
|
+
# RAGI - Ruby classes for implementing an AGI server for Asterisk
|
3
|
+
# The BSD License for RAGI follows.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2005, SNAPVINE LLC (www.snapvine.com)
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Redistribution and use in source and binary forms, with or without
|
9
|
+
# modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer.
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer in the
|
15
|
+
# documentation and/or other materials provided with the distribution.
|
16
|
+
# * Neither the name of SNAPVINE nor the names of its contributors
|
17
|
+
# may be used to endorse or promote products derived from this software
|
18
|
+
# without specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
24
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
module RAGI
|
32
|
+
# This class is useful for writing unit tests
|
33
|
+
class TestSocket
|
34
|
+
|
35
|
+
def initialize(params, messages)
|
36
|
+
@params = params
|
37
|
+
@messages = messages
|
38
|
+
@inParams = true
|
39
|
+
@currentIndex = 0
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.Exec(cmd, params)
|
43
|
+
[ "EXEC #{cmd} #{params}", "200 result=0"]
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.GetData(soundfile, result)
|
47
|
+
["GET DATA #{soundfile} 2000", "200 result=#{result} (timeout)"]
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.StreamFile(soundfile, escapeDigits, initialOffset, result, endpos)
|
51
|
+
["STREAM FILE #{soundfile} \"#{escapeDigits}\" #{initialOffset}",
|
52
|
+
"200 result=#{result} endpos=#{endpos}"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.PlaySound(soundfile)
|
56
|
+
[ "EXEC playback #{soundfile}", "200 result=0"]
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.SayNumber(number)
|
60
|
+
SayNumberFull(number, " \"*#\"")
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.SayNumberFull(number, escapeDigits)
|
64
|
+
[ "SAY NUMBER #{number} \"#{escapeDigits}\"", "200 result=0"]
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.HangUp()
|
68
|
+
[ "HANGUP", "200 result=0"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def print(msg)
|
72
|
+
if @inParams
|
73
|
+
raise StandardError, "Should not receive commands until parameters are parse"
|
74
|
+
end
|
75
|
+
|
76
|
+
if (!@messages[@currentIndex])
|
77
|
+
raise StandardError, "Too many messages received\nMessage =#{msg}= received"
|
78
|
+
end
|
79
|
+
|
80
|
+
if (msg != @messages[@currentIndex][0])
|
81
|
+
raise StandardError, "Unexpected message received\nMessage =#{msg}= received\nExpected =#{@messages[@currentIndex][0]}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def gets
|
86
|
+
if (@inParams) then
|
87
|
+
if (@currentIndex < @params.length) then
|
88
|
+
key = @params.keys[@currentIndex]
|
89
|
+
val = "#{key}: #{@params[@params.keys[@currentIndex]]}"
|
90
|
+
@currentIndex += 1
|
91
|
+
else
|
92
|
+
@currentIndex = 0
|
93
|
+
@inParams = false
|
94
|
+
val = ''
|
95
|
+
end
|
96
|
+
else
|
97
|
+
if (@currentIndex < @messages.length) then
|
98
|
+
val = @messages[@currentIndex][1]
|
99
|
+
@currentIndex += 1
|
100
|
+
else
|
101
|
+
raise StandardError, "Unexpected messages past end of test case"
|
102
|
+
@currentIndex = 0
|
103
|
+
val = '\n'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
val
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|