ragi 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|